home *** CD-ROM | disk | FTP | other *** search
/ Eagles Nest BBS 4 / Eagles_Nest_Mac_Collection_Disc_4.TOAST / Database Management / FoxPro25#1 / FoxPro 2.5 Disk - 1 Setup.image / Genscrn.prg / Genscrn.bin
Text File  |  1993-12-04  |  290KB  |  9,059 lines

  1. *:*****************************************************************************
  2. *:
  3. *: Procedure file: C:\FOXPROW\GENSCRN.PRG
  4. *:         System: GenScrn
  5. *:         Author: Microsoft Corp.
  6. *:      Copyright (c) 1990 - 1993 Microsoft Corp.
  7. *:  Last modified: 1/4/93 at 19:33:06
  8. *:
  9. *:      Documented              FoxDoc version 3.00a
  10. *:*****************************************************************************
  11. *
  12. * GENSCRN - Screen Code Generator.
  13. *
  14. * Copyright (c) 1990 - 1993 Microsoft Corp.
  15. * One Microsoft Way
  16. * Redmond, WA 98502
  17. *
  18. * Description:
  19. * This program generates code for objects designed and built with
  20. * FoxPro screen builder.
  21. *
  22. * Notes:
  23. * In this program, for clarity/readability reasons, we use variable
  24. * names that are longer than 10 characters.  Note, however, that only
  25. * the first 10 characters are significant.
  26. *
  27. PARAMETER m.projdbf, m.recno
  28. PRIVATE ALL
  29.  
  30. IF SET("TALK") = "ON"
  31.    SET TALK OFF
  32.    m.talkset = "ON"
  33. ELSE
  34.    m.talkset = "OFF"
  35. ENDIF
  36.  
  37. m.escape = SET("ESCAPE")
  38. ON ESCAPE
  39. SET ESCAPE OFF
  40. m.trbetween = SET("TRBET")
  41. SET TRBET OFF
  42. m.comp = SET("COMPATIBLE")
  43. SET COMPATIBLE FOXPLUS
  44. mdevice = SET("DEVICE")
  45. SET DEVICE TO SCREEN
  46.  
  47. *
  48. * Declare Global Constants
  49. *
  50. #DEFINE c_otscreen         1
  51. #DEFINE c_otworkarea       2
  52. #DEFINE c_otindex          3
  53. #DEFINE c_otrel               4
  54. #DEFINE c_ottext           5
  55. #DEFINE c_otline           6
  56. #DEFINE c_otbox            7
  57. #DEFINE c_otlist          11
  58. #DEFINE c_ottxtbut        12
  59. #DEFINE c_otradbut        13
  60. #DEFINE c_otchkbox        14
  61. #DEFINE c_otfield         15
  62. #DEFINE c_otpopup         16
  63. #DEFINE c_otpicture       17
  64. #DEFINE c_otinvbut        20
  65. #DEFINE c_otspinner       22
  66.  
  67. #DEFINE c_authorlen       45
  68. #DEFINE c_complen         45
  69. #DEFINE c_addrlen         45
  70. #DEFINE c_citylen         20
  71. #DEFINE c_statlen          5
  72. #DEFINE c_ziplen          10
  73. #DEFINE c_countrylen      40
  74.  
  75. #DEFINE c_sgsay            0
  76. #DEFINE c_sgget            1
  77. #DEFINE c_sgedit           2
  78. #DEFINE c_sgfrom           3
  79. #DEFINE c_sgbox            4
  80. #DEFINE c_sgboxd           5
  81. #DEFINE c_sgboxp           6
  82. #DEFINE c_sgboxc           7
  83.  
  84. * Determines whether SHOW snippets are checked for suspicious SHOW GETS statements
  85. #DEFINE c_checkshow        1
  86.  
  87. #DEFINE c_maxwinds        25
  88. #DEFINE c_maxpops         25
  89. #DEFINE c_maxscreens       5
  90. #DEFINE c_maxplatforms     4
  91. #DEFINE c_20scxflds          57
  92. #DEFINE c_scxflds         79
  93. #DEFINE c_pjxflds         31
  94. #DEFINE c_pjx20flds       33
  95.  
  96. #DEFINE c_esc            CHR(27)
  97. #DEFINE c_null            CHR(0)
  98. #DEFINE c_cret            CHR(13)
  99. #DEFINE c_lf            CHR(10)
  100. #DEFINE c_under            "_"
  101. #DEFINE c_single        "⁄ƒø≥Ÿƒ¿≥"
  102. #DEFINE c_double        "…Õª∫ºÕ»∫"
  103. #DEFINE c_panel            "€€€€€€€€"
  104. #DEFINE c_fromone        1
  105. #DEFINE c_untilend        0
  106.  
  107. #DEFINE c_error_1        "Minor"
  108. #DEFINE c_error_2        "Serious"
  109. #DEFINE c_error_3        "Fatal"
  110.  
  111. #DEFINE c_aliaslen   10   && maximum alias length
  112.  
  113. IF _MAC
  114.    m.g_dlgface = "Geneva"
  115.    m.g_dlgsize = 10.000
  116.    m.g_dlgstyle = ""
  117. ELSE
  118.    m.g_dlgface = "MS Sans Serif"
  119.    m.g_dlgsize = 8.000
  120.    m.g_dlgstyle = "B"
  121. ENDIF
  122.  
  123. #DEFINE c_pathsep  "\"
  124.  
  125. #DEFINE c_genexpr    0
  126. #DEFINE c_gencode    1
  127. #DEFINE c_genboth    -1
  128.  
  129. #DEFINE c_therm1      5
  130. #DEFINE c_therm2     15
  131. #DEFINE c_therm3     35
  132. #DEFINE c_therm4     60
  133. #DEFINE c_therm5     65
  134. #DEFINE c_therm6     70
  135. #DEFINE c_therm7     95
  136.  
  137. #DEFINE c_all 1
  138. m.g_picext = "PCT"   && Mac picture
  139. m.g_bmpext = "BMP"   && Windows bitmap
  140. m.g_icnext = "ICN"   && Mac icon
  141. m.g_icoext = "ICO"   && Windows icon
  142.  
  143. m.g_genparams = PARAMETERS()
  144. *
  145. * Declare Variables
  146. *
  147. STORE "" TO m.cursor, m.consol, m.bell, m.exact, ;
  148.    m.safety, m.fixed, m.print, m.delimiters, m.unique, mudfparms, ;
  149.    m.fields, mfieldsto, m.mdecpoint, m.origpretext, m.mcollate, m.mmacdesk
  150. STORE 0 TO m.deci, m.memowidth
  151.  
  152. m.g_closefiles = .F.           && Generate code to close files?
  153. m.g_current    = ""            && current DBF
  154. m.g_defasch1   = 0               && Default color scheme 1
  155. m.g_defasch2   = 0               && Default color scheme 2
  156. m.g_defwin     = .F.           && Generate code to define windows?
  157. m.g_errlog     = ""               && Path + name of .ERR file
  158. m.g_homedir    = ""               && Application Home Directory
  159. m.g_idxfile    = 'idxfile.idx' && Index file
  160. m.g_itse       = c_null           && Designating character from #ITSEXPRESSION
  161. m.g_lastwindow = ""            && Name of last window defined
  162. m.g_keyno      = 0
  163. m.g_havehand = .F.
  164. m.g_redefi     = .F.           && Don't redefine windows
  165. m.g_screen     = 0             && Screen currently being generated.  Also used in error messages.
  166. m.g_nscreens   = 0             && Number of screens
  167. m.g_nwindows   = 0             && Number of unique windows in this platform
  168. m.g_multreads  = .F.           && Multiple reads?
  169. m.g_openfiles  = .F.           && Generate code to open files?
  170. m.g_orghandle  = -1            && File handle for ctrl file
  171. m.g_outfile    = ""            && Output file name
  172. m.g_projalias  = ""            && Project database alias
  173. m.g_projpath   = ""
  174. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  175. m.g_windclauses= ""            && #WCLAUSES parameters for DEFINE WINDOW
  176. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  177. m.g_readcycle  = .F.           && READ CYCLE?
  178. m.g_readlock   = .F.           && READ LOCK/NOLOCK?
  179. m.g_readmodal  = .F.           && READ MODAL?
  180. m.g_readborder = .F.           && READ BORDER?
  181. m.g_relwin     = .F.           && Generate code to release windows?
  182. m.g_moddesktop = .F.
  183. m.g_snippcnt   = 0             && Count of snippets
  184. m.g_somepops   = .F.           && Any Generated popups?
  185. m.g_status     = 0
  186. m.g_thermwidth = 0             && Thermometer width
  187. m.g_tmpfile    = SYS(3)+".tmp" && Temporary file
  188. m.g_tmphandle  = -1            && File handle for tmp file
  189. m.g_windows    = .F.           && Any windows in screen files?
  190. m.g_withlist   = ""
  191. m.g_workarea   = 0
  192. m.g_genvers       = ""            && version we are generating for
  193. m.g_thisvers   = ""            && version we are running under now
  194. m.g_graphic    = .F.
  195. m.g_isfirstproc= .T.           && is this the first procedure emitted?
  196. m.g_procsmatch = .F.           && are cleanup snippets for all platforms identical
  197. m.g_noread     = .F.           && omit the read statement?
  198. m.g_noreadplain= .F.           && omit the read statement and the SET TALK TO.. statements?
  199. m.g_dualoutput = .F.           && generating for Mac on Windows (& etc.) ?
  200.  
  201. m.g_boxstrg = ['ƒ','ƒ','≥','≥','⁄','ø','¿','Ÿ','ƒ','ƒ','≥','≥','⁄','ø','¿','Ÿ']
  202.  
  203. m.g_validtype  = ""
  204. m.g_validname  = ""
  205. m.g_whentype   = ""
  206. m.g_whenname   = ""
  207. m.g_actitype   = ""
  208. m.g_actiname   = ""
  209. m.g_deattype   = ""
  210. m.g_deatname   = ""
  211. m.g_showtype   = ""
  212. m.g_showname   = ""
  213. m.g_showexpr   = ""
  214.  
  215. m.g_sect1start = 0
  216. m.g_sect2start = 0
  217.  
  218. m.g_devauthor  = PADR("Author's Name",c_authorlen," ")
  219. m.g_devcompany = PADR("Company Name",c_complen, " ")
  220. m.g_devaddress = PADR("Address",c_addrlen," ")
  221. m.g_devcity    = PADR("City",c_citylen," ")
  222. m.g_devstate   = "  "
  223. m.g_devzip     = PADR("Zip",c_ziplen," ")
  224. m.g_devctry    = PADR("Country",c_countrylen, " ")
  225.  
  226. m.g_allplatforms = .T.            && generate for all platforms in the SCX?
  227. m.g_numplatforms = 1              && number of platforms we are generating for
  228. m.g_parameter    = ""             && the parameter statement for this SPR
  229. m.g_areacount    = 1              && index into g_areas to count workareas we use
  230. m.g_dblampersand = CHR(38) + CHR(38)   && used in some tight loops.  Concatenate just once here.
  231.  
  232. DO CASE
  233. CASE AT("WINDOWS", UPPER(VERSION())) <> 0
  234.    m.g_thisvers = "WINDOWS"
  235.    m.g_graphic  = .T.
  236. CASE AT("MAC", UPPER(VERSION())) <> 0
  237.    m.g_thisvers = "MAC"
  238.    m.g_graphic  = .T.
  239. CASE AT("UNIX", UPPER(VERSION())) <> 0
  240.    m.g_thisvers = "UNIX"
  241.    m.g_graphic  = .F.
  242. CASE AT("FOXPRO", UPPER(VERSION())) <> 0
  243.    m.g_thisvers = "DOS"
  244.    m.g_graphic  = .F.
  245. OTHERWISE
  246.    DO errorhandler WITH "Unknown FoxPro platform",LINENO(),c_error_3
  247. ENDCASE
  248.  
  249. STORE "" TO m.g_corn1, m.g_corn2, m.g_corn3, m.g_corn4, m.g_corn5, ;
  250.    m.g_corn6, m.g_verti2
  251. STORE "*" TO  m.g_horiz, m.g_verti1
  252.  
  253. * This array stores the names of the DBFs in the environment for this platform
  254. DIMENSION g_dbfs[1]
  255. g_dbfs = ""
  256.  
  257. * If you add arrays that are based on C_MAXSCREENS, remember to check PrepScreens().
  258. * You'll probably need to add the array name there so that if the number of screens
  259. * exceeds C_MAXSCREENS, your array gets expanded too.
  260.  
  261. *    generated popup names associated with scollable lists.
  262. *
  263. *    g_popups[*,1] - screen basename
  264. *    g_popups[*,2] - record number
  265. *    g_popups[*,3] - generated popup name
  266. *
  267. DIMENSION g_popups[C_MAXPOPS,3]
  268. g_popups = ""
  269.  
  270. *     screen file name array definition
  271. *
  272. *     g_screens[*,1] - screen fully qualified name
  273. *     g_screens[*,2] - window name if any
  274. *     g_screens[*,3] - recno in proj dbf
  275. *    g_screens[*,4] - initially opened?
  276. *    g_screens[*,5] - alias
  277. *    g_screens[*,6] - 2.0 screen file?
  278. *    g_screens[*,7] - Platform to generate from
  279. *
  280. DIMENSION g_screens[C_MAXSCREENS,7]
  281. g_screens = ""
  282.  
  283. * Array to store window stack.
  284. * g_wndows[*,1]  - Window name
  285. * g_wndows[*,2]  - Window sequence
  286. DIMENSION g_wndows[C_MAXWINDS,2]
  287. g_wndows = ""
  288.  
  289. * Store the substitution string for window names
  290. DIMENSION g_wnames[C_MAXSCREENS, C_MAXPLATFORMS]
  291. g_wnames = ""
  292.  
  293. * g_platforms holds a list of platforms in common among all screens
  294. DIMENSION g_platforms[C_MAXSCREENS]
  295. g_platforms = ""
  296.  
  297. * g_platprocs is a parallel array to g_platforms.  It holds the name
  298. * of the procedure to contain the setup snippet and all the @SAYs 
  299. * and @GETs for the corresponding platform.
  300. DIMENSION g_platproc[C_MAXSCREENS]
  301. g_platproc = ""
  302.  
  303. * g_areas holds a list of areas we opened files in during this gen and that
  304. * we need to close on exit.
  305. DIMENSION g_areas[256]
  306. g_areas = 0
  307.  
  308. * g_firstproc holds the line number of the first PROCEDURE or FUNCTION in
  309. * the cleanup snippet of each screen.
  310. DIMENSION g_firstproc[C_MAXSCREENS]
  311. g_firstproc = 0
  312.  
  313. DIMENSION g_platlist[C_MAXPLATFORMS]
  314. g_platlist[1] = "DOS"
  315. g_platlist[2] = "WINDOWS"
  316. g_platlist[3] = "MAC"
  317. g_platlist[4] = "UNIX"
  318.  
  319. DIMENSION g_procs[1,C_MAXPLATFORMS+3]
  320. * First column is a procedure name
  321. * Second through n-th column is the line number in the cleanup snippet where
  322. *    a procedure with this name starts.
  323. * C_MAXPLATFORMS+2 column is a 1 if this procedure has been emitted.
  324. * C_MAXPLATFORMS+3 column holds the parameter statement, if any.
  325. * One row for each unique procedure name found in the cleanup snippet for any platform.
  326. g_procs = -1
  327. g_procs[1,1] = ""
  328. g_procs[1,C_MAXPLATFORMS+3] = ""
  329. g_procnames = 0   && the number we've found so far
  330.  
  331. **
  332. ** Main program
  333. **
  334.  
  335. m.onerror = ON("ERROR")
  336. ON ERROR DO errorhandler WITH MESSAGE(), LINENO(), c_error_3
  337.  
  338. IF m.g_genparams < 2
  339.    DO errorhandler WITH "Invalid number of parameters passed to"+;
  340.       " the generator",LINENO(),c_error_3
  341.    RETURN m.g_status
  342. ENDIF
  343.  
  344. DO setall
  345.  
  346. IF openprojdbf(m.projdbf, m.recno) AND prepscreens(m.g_thisvers) AND prepplatform()
  347.    DO BUILD
  348. ENDIF
  349.  
  350. DO cleanup
  351.  
  352. RETURN m.g_status
  353.  
  354. **
  355. ** Code Responsible for Genscrn's environment setting.
  356. **
  357.  
  358. *!*****************************************************************************
  359. *!
  360. *!      Procedure: SETALL
  361. *!
  362. *!      Called by: GENSCRN.PRG
  363. *!
  364. *!*****************************************************************************
  365. PROCEDURE setall
  366. *)
  367. *) SETALL - Create program's environment.
  368. *)
  369. *) Description:
  370. *) Save the user's environment that is being modified by the GENSCRN,
  371. *) then issue various SET commands.
  372. *)
  373. CLEAR PROGRAM
  374. CLEAR GETS
  375.  
  376. m.g_workarea = SELECT()
  377. m.delimiters = SET('TEXTMERGE',1)
  378. SET TEXTMERGE DELIMITERS TO
  379. SET TEXTMERGE NOSHOW
  380. mudfparms = SET('UDFPARMS')
  381. SET UDFPARMS TO VALUE
  382.  
  383. m.mfieldsto = SET("FIELDS",1)
  384. m.fields = SET("FIELDS")
  385. m.memowidth = SET("MEMOWIDTH")
  386. SET MEMOWIDTH TO 256
  387. m.cursor = SET("CURSOR")
  388. SET CURSOR OFF
  389. m.consol = SET("CONSOLE")
  390. SET CONSOLE OFF
  391. m.bell = SET("BELL")
  392. SET BELL OFF
  393. m.exact = SET("EXACT")
  394. SET EXACT ON
  395. m.safety = SET("SAFETY")
  396. m.deci = SET("DECIMALS")
  397. SET DECIMALS TO 0
  398. m.mdecpoint = SET("POINT")
  399. SET POINT TO "."
  400. m.fixed = SET("FIXED")
  401. SET FIXED ON
  402. m.print = SET("PRINT")
  403. SET PRINT OFF
  404. m.unique = SET("UNIQUE")
  405. SET UNIQUE OFF
  406. m.mcollate = SET("COLLATE")
  407. SET COLLATE TO "machine"
  408. #if "MAC" $ UPPER(VERSION(1))
  409.    IF _MAC
  410.       m.mmacdesk = SET("MACDESKTOP")
  411.       SET MACDESKTOP ON
  412.     ENDIF
  413. #endif
  414. m.origpretext = _PRETEXT
  415. _PRETEXT = ""
  416. RETURN
  417.  
  418. *!*****************************************************************************
  419. *!
  420. *!      Procedure: CLEANUP
  421. *!
  422. *!      Called by: GENSCRN.PRG
  423. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  424. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  425. *!
  426. *!          Calls: CLEANSCRN          (procedure in GENSCRN.PRG)
  427. *!               : CLEARAREAS         (procedure in GENSCRN.PRG)
  428. *!
  429. *!*****************************************************************************
  430. PROCEDURE cleanup
  431. *)
  432. *) CLEANUP - Restore environment to pre-execution state.
  433. *)
  434. *) Description:
  435. *) Put SET command settings back the way we found them.
  436. *)
  437. PRIVATE m.i, m.delilen, m.ldelimi, m.rdelimi
  438. IF EMPTY(m.g_projalias)
  439.    RETURN
  440. ENDIF
  441. SELECT (m.g_projalias)
  442. USE
  443. DO cleanscrn
  444. DO clearareas  && clear the workareas we opened during this run
  445. SELECT (m.g_workarea)
  446.  
  447. DELETE FILE (m.g_tmpfile)
  448. DELETE FILE (m.g_idxfile)
  449.  
  450. m.delilen = LEN(m.delimiters)
  451. m.ldelimi = SUBSTR(m.delimiters,1,;
  452.    IIF(MOD(m.delilen,2)=0,m.delilen/2,CEILING(m.delilen/2)))
  453. m.rdelimi = SUBSTR(m.delimiters,;
  454.    IIF(MOD(m.delilen,2)=0,m.delilen/2+1,CEILING(m.delilen/2)+1))
  455. SET TEXTMERGE DELIMITERS TO m.ldelimi, m.rdelimi
  456.  
  457. SET FIELDS TO &mfieldsto
  458. IF m.fields = "ON"
  459.    SET FIELDS ON
  460. ELSE
  461.    SET FIELDS OFF
  462. ENDIF
  463. IF m.cursor = "ON"
  464.    SET CURSOR ON
  465. ELSE
  466.    SET CURSOR OFF
  467. ENDIF
  468. IF m.consol = "ON"
  469.    SET CONSOLE ON
  470. ELSE
  471.    SET CONSOLE OFF
  472. ENDIF
  473. IF m.escape = "ON"
  474.    SET ESCAPE ON
  475. ELSE
  476.    SET ESCAPE OFF
  477. ENDIF
  478. IF m.bell = "ON"
  479.    SET BELL ON
  480. ELSE
  481.    SET BELL OFF
  482. ENDIF
  483. IF m.exact = "ON"
  484.    SET EXACT ON
  485. ELSE
  486.    SET EXACT OFF
  487. ENDIF
  488. IF m.safety = "ON"
  489.    SET SAFETY ON
  490. ELSE
  491.    SET SAFETY OFF
  492. ENDIF
  493. IF m.comp = "ON"
  494.    SET COMPATIBLE ON
  495. ENDIF
  496. IF m.print = "ON"
  497.    SET PRINT ON
  498. ENDIF
  499. SET DECIMALS TO m.deci
  500. SET MEMOWIDTH TO m.memowidth
  501. SET DEVICE TO &mdevice
  502. SET UDFPARMS TO &mudfparms
  503. SET POINT TO "&mdecpoint"
  504. SET COLLATE TO "&mcollate"
  505. #if "MAC" $ UPPER(VERSION(1))
  506.    IF _MAC
  507.       SET MACDESKTOP &mmacdesk
  508.     ENDIF
  509. #endif
  510. IF m.fixed = "OFF"
  511.    SET FIXED OFF
  512. ENDIF
  513. IF m.trbetween = "ON"
  514.    SET TRBET ON
  515. ENDIF
  516. IF m.talkset = "ON"
  517.    SET TALK ON
  518. ENDIF
  519. IF m.unique = "ON"
  520.    SET UNIQUE ON
  521. ENDIF
  522. SET MESSAGE TO
  523. _PRETEXT = m.origpretext
  524. * Leave this array if dbglevel is defined.  Used for profiling.
  525. * IF TYPE("dbglevel") = "U"
  526. *   RELEASE ticktock
  527. * ENDIF
  528.  
  529. ON ERROR &onerror
  530. RETURN
  531.  
  532. *!*****************************************************************************
  533. *!
  534. *!      Procedure: CLEANSCRN
  535. *!
  536. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  537. *!
  538. *!*****************************************************************************
  539. PROCEDURE cleanscrn
  540. *)
  541. *) CLEANSCRN - Clean up after each screen set generation, once per platform
  542. *)
  543. PRIVATE m.i
  544. FOR m.i = 1 TO m.g_nscreens
  545.    m.g_screen = i
  546.    IF NOT EMPTY(g_screens[m.i,4])
  547.       LOOP
  548.    ENDIF
  549.    IF USED(g_screens[m.i,5])
  550.       SELECT (g_screens[m.i,5])
  551.       USE
  552.    ENDIF
  553. ENDFOR
  554. m.g_screen = 0
  555. RETURN
  556.  
  557. *!*****************************************************************************
  558. *!
  559. *!      Procedure: BUILDENABLE
  560. *!
  561. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  562. *!
  563. *!          Calls: PREPFILE           (procedure in GENSCRN.PRG)
  564. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  565. *!
  566. *!*****************************************************************************
  567. PROCEDURE buildenable
  568. *)
  569. *> BUILDENABLE - Enable code generation.
  570. *)
  571. *) Description:
  572. *) Call prepfile to open output file(s).
  573. *) If error(s) encountered in prepfile then exit, otherwise
  574. *) SET TEXTMERGE ON
  575. *)
  576. *) Returns: .T. on success; .F. on failure
  577. *)
  578. DO prepfile WITH m.g_outfile, m.g_orghandle
  579. DO prepfile WITH m.g_tmpfile, m.g_tmphandle
  580.  
  581. SET TEXTMERGE ON
  582. ON ESCAPE DO eschandler
  583. SET ESCAPE ON
  584. RETURN
  585.  
  586. *!*****************************************************************************
  587. *!
  588. *!      Procedure: BUILDDISABLE
  589. *!
  590. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  591. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  592. *!
  593. *!          Calls: CLOSEFILE          (procedure in GENSCRN.PRG)
  594. *!
  595. *!*****************************************************************************
  596. PROCEDURE builddisable
  597. *)
  598. *) BUILDDISABLE - Disable code generation.
  599. *)
  600. *) Description:
  601. *) Issue the command SET TEXTMERGE OFF.
  602. *) Close the generated output file.
  603. *) Close the temporary file.
  604. *) If anything goes wrong display appropriate message to the user.
  605. *)
  606. SET ESCAPE OFF
  607. ON ESCAPE
  608. SET TEXTMERGE OFF
  609. IF m.g_havehand
  610.    DO closefile WITH m.g_orghandle
  611.    DO closefile WITH m.g_tmphandle
  612. ENDIF
  613. RETURN
  614.  
  615. *!*****************************************************************************
  616. *!
  617. *!      Procedure: PREPPARAMS
  618. *!
  619. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  620. *!
  621. *!          Calls: CHECKPARAM()       (function  in GENSCRN.PRG)
  622. *!
  623. *!*****************************************************************************
  624. PROCEDURE prepparams
  625. *)
  626. *) PREPPARAMS - Read through each of the platforms on screen 1
  627. *)              and ensure that any parameter statements in #SECTION 1
  628. *)              are identical.
  629. *)
  630. PRIVATE m.i, m.j, m.dbalias, m.thisparam
  631. m.g_screen = 1
  632. m.dbalias = g_screens[m.g_screen,5]
  633. SELECT (m.dbalias)
  634. DO CASE
  635. CASE g_screens[m.g_screen,6] OR !multiplat()
  636.    * DOS 2.0 screen or just one 2.5 platform being generated
  637.    GO TOP
  638.    RETURN checkparam(m.g_screen)
  639.  
  640. OTHERWISE
  641.    FOR m.j = 1 TO c_maxplatforms
  642.       LOCATE FOR ALLTRIM(UPPER(platform)) = g_platlist[m.j] AND objtype = c_otscreen
  643.       DO CASE
  644.       CASE !FOUND() OR EMPTY(setupcode)
  645.          LOOP
  646.       CASE !checkparam(m.g_screen)
  647.          RETURN .F.
  648.       ENDCASE
  649.    ENDFOR
  650. ENDCASE
  651. m.g_screen = 0
  652. RETURN .T.
  653.  
  654. *!*****************************************************************************
  655. *!
  656. *!       Function: CLEANPARAM
  657. *!
  658. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  659. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  660. *!
  661. *!*****************************************************************************
  662. FUNCTION cleanparam
  663. *)
  664. *) CLEANPARAM - Clean up a parameter string so that it may be compared with another one.
  665. *)              This function replaces tabs with spaces, capitalizes the string, merges
  666. *)              forces single spacing, and strips out CR/LF characters.
  667. *)
  668. PARAMETER m.p, m.cp
  669. m.cp = UPPER(ALLTRIM(CHRTRAN(m.p,";"+CHR(13)+CHR(10),"")))   && drop CR/LF and continuation chars
  670. m.cp = CHRTRAN(m.cp,CHR(9),' ')   && tabs to spaces
  671. DO WHILE AT('  ',m.cp) > 0         && reduce multiple spaces to a single space
  672.    m.cp = STRTRAN(m.cp,'  ',' ')
  673. ENDDO
  674. DO WHILE AT(', ',m.cp) > 0         && drop spaces after commas
  675.    m.cp = STRTRAN(m.cp,', ',',')
  676. ENDDO
  677. RETURN m.cp
  678.  
  679. *!*****************************************************************************
  680. *!
  681. *!       Function: CHECKPARAM
  682. *!
  683. *!      Called by: PREPPARAMS         (procedure in GENSCRN.PRG)
  684. *!
  685. *!          Calls: GETPARAM()         (function  in GENSCRN.PRG)
  686. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  687. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  688. *!
  689. *!*****************************************************************************
  690. FUNCTION checkparam
  691. *)
  692. *) CHECKPARAM - See if this parameter statement matches others we have found. Generate
  693. *)               an error message if it doesn't.  g_parameter is empty if we haven't
  694. *)               seen any parameter statements yet, or it contains the variables in the
  695. *)               parameter statement (but not the PARAMETERS keyword) if we have seen one
  696. *)               before.
  697. *)
  698. PARAMETER m.i
  699. PRIVATE m.thisparam
  700. m.thisparam = getparam("setupcode")  && get parameter from setup snippet at current record position
  701.  
  702. IF !EMPTY(m.thisparam)
  703.    IF !EMPTY(m.g_parameter) AND !(cleanparam(m.thisparam) == cleanparam(m.g_parameter))
  704.       DO errorhandler WITH "DOS and Windows setup code has different parameters", ;
  705.          LINENO(), c_error_3
  706.       RETURN .F.
  707.    ELSE
  708.       g_parameter = m.thisparam
  709.    ENDIF
  710. ENDIF
  711. RETURN .T.
  712.  
  713. *!*****************************************************************************
  714. *!
  715. *!      Procedure: PREPPLATFORM
  716. *!
  717. *!      Called by: GENSCRN.PRG
  718. *!
  719. *!*****************************************************************************
  720. PROCEDURE prepplatform
  721. *)
  722. *) PREPPLATFORM - Create an array of platform names in the screen set.  Make sure that
  723. *)                there is at least one common platform across all SCXs in the screen set.
  724. *)                g_platforms comes out of this procedure containing the intersection of
  725. *)                the set of platforms in each screen.  If there are no common platforms
  726. *)                across all screens, it will be empty.
  727. *)
  728. PRIVATE m.i, m.j, m.firstscrn, m.p_cur, m.tempplat, m.numtodel, m.in_area, ;
  729.    m.rcount
  730. IF m.g_nscreens <= 0
  731.    RETURN .F.
  732. ENDIF
  733.  
  734. DIMENSION t_platforms[ALEN(g_platforms)]
  735. m.in_area = SELECT()
  736. IF g_screens[1,6]         && First screen is a DOS 2.0 screen
  737.    g_platforms = ""
  738.    g_platforms[1] = "DOS"
  739. ELSE
  740.    IF _DOS
  741.       * Avoid selecting into an array to conserve memory
  742.       SELECT DISTINCT platform FROM (g_screens[1,1]) INTO CURSOR curstemp ;
  743.          ORDER BY platform
  744.       m.rcount = _TALLY
  745.       SELECT curstemp
  746.       DIMENSION g_platforms[m.rcount]
  747.       GOTO TOP
  748.       FOR m.i = 1 TO m.rcount
  749.          g_platforms[m.i] = curstemp->platform
  750.          SKIP
  751.       ENDFOR
  752.       USE                                             && get rid of the cursor
  753.    ELSE
  754.       SELECT DISTINCT platform FROM (g_screens[1,1]) INTO ARRAY g_platforms ;
  755.          ORDER BY platform
  756.    ENDIF
  757. ENDIF
  758.  
  759. m.numtodel = 0   && number of array elements to delete
  760. FOR m.i = 2 TO m.g_nscreens
  761.    m.g_screen = m.i
  762.    IF g_screens[m.i,6]   && DOS 2.0 screen
  763.       DIMENSION t_platforms[1]
  764.       t_platforms = ""
  765.       t_platforms[1] = "DOS"
  766.    ELSE
  767.       IF _DOS
  768.          * Avoid selecting into an array to conserve memory
  769.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) INTO CURSOR curstemp ;
  770.             ORDER BY platform
  771.          m.rcount = _TALLY
  772.          SELECT curstemp
  773.          DIMENSION t_platforms[m.rcount]
  774.          GOTO TOP
  775.          FOR m.k = 1 TO m.rcount
  776.             t_platforms[m.k] = curstemp->platform
  777.             SKIP
  778.          ENDFOR
  779.          USE                                             && get rid of the cursor
  780.       ELSE
  781.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) INTO ARRAY t_platforms ;
  782.             ORDER BY platform
  783.       ENDIF
  784.    ENDIF
  785.  
  786.    * Update g_platforms with the intersection of g_platforms
  787.    *  and t_platforms
  788.    m.j = 1
  789.    DO WHILE m.j < ALEN(g_platforms) -  m.numtodel
  790.       IF !INLIST(TYPE("g_platforms[m.j]"),"L","U") ;
  791.             AND ASCAN(t_platforms,g_platforms[m.j]) = 0
  792.          =ADEL(g_platforms,m.j)
  793.          m.numtodel = m.numtodel + 1
  794.       ELSE
  795.          m.j = m.j + 1
  796.       ENDIF
  797.    ENDDO
  798.  
  799. ENDFOR
  800. SELECT (m.in_area)
  801.  
  802. m.g_screen = 0
  803. * Shrink the unique platform array if necessary
  804. DIMENSION g_platforms[ALEN(g_platforms)-m.numtodel]
  805.  
  806. IF ALEN(g_platforms) <= 0 OR EMPTY(g_platforms[1])
  807.    WAIT WINDOW  "No common platforms in these screens.  Press any key."
  808.    CANCEL
  809. ELSE
  810.    FOR m.j = 1 TO ALEN(g_platforms)
  811.       g_platforms[m.j] = UPPER(ALLTRIM(g_platforms[m.j]))
  812.    ENDFOR
  813.  
  814.    * If the current platform is in the list of common platforms, put it at the top
  815.    m.p_cur = ASCAN(g_platforms, m.g_thisvers)
  816.    IF m.p_cur > 1
  817.       m.tempplat = g_platforms[1]
  818.       g_platforms[1] = g_platforms[m.p_cur]
  819.       g_platforms[m.p_cur] = m.tempplat
  820.    ENDIF
  821. ENDIF
  822. RETURN .T.
  823.  
  824. *!*****************************************************************************
  825. *!
  826. *!      Procedure: PREPFILE
  827. *!
  828. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  829. *!
  830. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  831. *!
  832. *!*****************************************************************************
  833. PROCEDURE prepfile
  834. *)
  835. *) PREPFILE - Create and open the application output file.
  836. *)
  837. *) Description:
  838. *) Create or open a file that will hold the generated application.
  839. *) If error(s) encountered at any time issue an error message
  840. *) and return .F.
  841. *)
  842. PARAMETER m.filename, m.ifp
  843. PRIVATE m.msg
  844. m.ifp = FCREATE(m.filename)
  845.  
  846. IF (m.ifp = -1)
  847.    m.msg = "Cannot open "+LOWER(m.filename)
  848.    m.g_havehand = .F.
  849.    DO errorhandler WITH m.msg, LINENO(), c_error_3
  850. ELSE
  851.    m.g_havehand = .T.
  852. ENDIF
  853. RETURN
  854.  
  855. *!*****************************************************************************
  856. *!
  857. *!      Procedure: CLOSEFILE
  858. *!
  859. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  860. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  861. *!
  862. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  863. *!
  864. *!*****************************************************************************
  865. PROCEDURE closefile
  866. *)
  867. *) CLOSEFILE - Close a low level file opened with FCREATE.
  868. *)
  869. PARAMETER m.ifp
  870. IF (m.ifp > 0) AND !FCLOSE(m.ifp)
  871.    DO errorhandler WITH "Unable to close the generated file",;
  872.       LINENO(), c_error_2
  873. ENDIF
  874. RETURN
  875.  
  876. *!*****************************************************************************
  877. *!
  878. *!       Function: PREPSCREENS
  879. *!
  880. *!      Called by: GENSCRN.PRG
  881. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  882. *!
  883. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  884. *!               : SCREENUSED()       (function  in GENSCRN.PRG)
  885. *!               : NOTEAREA           (procedure in GENSCRN.PRG)
  886. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  887. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  888. *!               : PREPWNAMES         (procedure in GENSCRN.PRG)
  889. *!
  890. *!*****************************************************************************
  891. FUNCTION prepscreens
  892. *)
  893. *) PREPSCREENS - Prepare screen file(s) for processing.
  894. *)
  895. *) Description:
  896. *) Called once per platform.
  897. *)
  898. *) Open PJX database, index it to find all screen files belonging
  899. *) to a screen set if part of a project.
  900. *)
  901. *) Open all screen file(s).  If screen file already opened, then
  902. *) select it.  Assign unique aliases to screen with name conflicts.
  903. *) If error is encountered while opening any of the screen files
  904. *) this program will be aborted.
  905. *)
  906. PARAMETER m.gen_version
  907.  
  908. PRIVATE m.status, m.projdbf, m.saverec, m.dbname, m.dbalias
  909. m.status = .T.
  910.  
  911. SELECT (m.g_projalias)
  912. SET SAFETY OFF
  913. INDEX ON STR(scrnorder) TO (m.g_idxfile) COMPACT
  914. SET SAFETY ON
  915. GO TOP
  916. SCAN FOR NOT DELETED() AND setid = m.g_keyno AND TYPE = 's'
  917.    m.saverec = RECNO()
  918.    m.dbname  = FULLPATH(ALLTRIM(name), m.g_projpath)
  919.    if right(m.dbname,1) = ":"
  920.       m.dbname = m.dbname + justfname(name)
  921.    endif
  922.    m.g_nscreens = m.g_nscreens + 1
  923.  
  924.    IF MOD(m.g_nscreens,5)=0
  925.       DIMENSION g_screens[ALEN(g_screens,1)+5,7]
  926.       DIMENSION g_wnames [ALEN(g_wnames)+5,C_MAXPLATFORMS]
  927.       DIMENSION g_platforms [ALEN(g_platforms)+5]
  928.       DIMENSION g_firstproc [ALEN(g_firstproc)+5]
  929.    ENDIF
  930.  
  931.    m.dbalias = LEFT(basename(m.dbname), c_aliaslen)
  932.    IF screenused(m.dbalias, m.dbname)
  933.       g_screens[m.g_nscreens,4] = .T.
  934.    ELSE
  935.       g_screens[m.g_nscreens,4] = .F.
  936.         IF FILE(m.dbname)
  937.          SELECT 0
  938.          USE (m.dbname) AGAIN ALIAS (g_screens[m.g_nscreens,5])
  939.          DO notearea
  940.         ELSE
  941.            DO errorhandler WITH "Could not find SCX file: "+m.dbname, ;
  942.                LINENO(),c_error_2
  943.             RETURN .F.
  944.        ENDIF
  945.    ENDIF
  946.  
  947.    DO CASE
  948.    CASE FCOUNT() = c_scxflds
  949.       LOCATE FOR platform = m.gen_version
  950.       IF FOUND()
  951.          g_screens[m.g_nscreens,6] = .F.
  952.          g_screens[m.g_nscreens,7] = platform
  953.       ELSE
  954.          g_screens[m.g_nscreens,6] = .F.
  955.          g_screens[m.g_nscreens,7] = getplatform()
  956.       ENDIF
  957.    CASE FCOUNT() = c_20scxflds
  958.       g_screens[m.g_nscreens,6] = .T.
  959.       g_screens[m.g_nscreens,7] = "DOS"
  960.    OTHERWISE
  961.       DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  962.          c_error_2
  963.       RETURN .F.
  964.    ENDCASE
  965.    g_screens[m.g_nscreens,1] = m.dbname
  966.  
  967.    IF NOT EMPTY(STYLE)
  968.       IF EMPTY(name)
  969.          g_screens[m.g_nscreens,2] = LOWER(SYS(2015))
  970.       ELSE
  971.          g_screens[m.g_nscreens,2] = ALLTRIM(LOWER(name))
  972.       ENDIF
  973.       DO prepwnames WITH m.g_nscreens
  974.    ENDIF
  975.  
  976.    SELECT (m.g_projalias)
  977.    GOTO RECORD m.saverec
  978.    g_screens[m.g_nscreens,3] = m.saverec
  979. ENDSCAN
  980.  
  981. RETURN m.status
  982.  
  983. *!*****************************************************************************
  984. *!
  985. *!       Function: NEWWINDOWS
  986. *!
  987. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  988. *!
  989. *!*****************************************************************************
  990. FUNCTION newwindows
  991. * Initialize the windows name array and other window-related
  992. * variables for each platform.
  993. g_wndows = ""                  && array of window names
  994. m.g_nwindows = 0               && number of windows
  995. m.g_lastwindow = ""            && name of last window generated for this platform
  996. RETURN
  997.  
  998. *!*****************************************************************************
  999. *!
  1000. *!       Function: NEWSCHEMES
  1001. *!
  1002. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1003. *!
  1004. *!*****************************************************************************
  1005. FUNCTION newschemes
  1006. *)
  1007. *) NEWSCHEMES - Initialize the color schemes for each screen/platform
  1008. *)
  1009. m.g_defasch  = 0
  1010. m.g_defasch2 = 0
  1011. RETURN
  1012.  
  1013. *!*****************************************************************************
  1014. *!
  1015. *!       Function: NEWDBFS
  1016. *!
  1017. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1018. *!
  1019. *!*****************************************************************************
  1020. FUNCTION newdbfs
  1021. *)
  1022. *) NEWDBFS - Initialize the databases name array for each platform
  1023. *)
  1024. m.g_dbfs = ""
  1025. RETURN
  1026.  
  1027. *!*****************************************************************************
  1028. *!
  1029. *!      Procedure: NEWREADCLAUSES
  1030. *!
  1031. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1032. *!
  1033. *!*****************************************************************************
  1034. PROCEDURE newreadclauses
  1035. *)
  1036. *) NEWREADCLAUSES - Initialize the variables that control which READ and WINDOW clauses are
  1037. *)                    emitted.
  1038. *)
  1039. m.g_validtype  = ""
  1040. m.g_validname  = ""
  1041. m.g_whentype   = ""
  1042. m.g_whenname   = ""
  1043. m.g_actitype   = ""
  1044. m.g_actiname   = ""
  1045. m.g_deattype   = ""
  1046. m.g_deatname   = ""
  1047. m.g_showtype   = ""
  1048. m.g_showname   = ""
  1049. m.g_showexpr   = ""
  1050. RETURN
  1051.  
  1052. *!*****************************************************************************
  1053. *!
  1054. *!      Procedure: NEWDIRECTIVES
  1055. *!
  1056. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1057. *!
  1058. *!*****************************************************************************
  1059. PROCEDURE newdirectives
  1060. m.g_windclauses= ""            && #WCLAUSES directive
  1061. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  1062. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  1063. RETURN
  1064.  
  1065. *!*****************************************************************************
  1066. *!
  1067. *!       Function: GETPLATFORM
  1068. *!
  1069. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1070. *!
  1071. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1072. *!
  1073. *!*****************************************************************************
  1074. FUNCTION getplatform
  1075. *)
  1076. *) GETPLATFORM - Find which Platform we are supposed to generate for.  If we are trying to
  1077. *)               generate for Windows, but there are no windows records in the SCX, use
  1078. *)               this function to determine which records to use.
  1079. *)
  1080. IF m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC'
  1081.    LOCATE FOR platform = IIF(m.g_genvers = 'WINDOWS', 'MAC', 'WINDOWS')
  1082.    IF FOUND()
  1083.       RETURN platform
  1084.    ELSE
  1085.       LOCATE FOR platform = 'DOS'
  1086.       IF FOUND()
  1087.          RETURN 'DOS'
  1088.       ELSE
  1089.          LOCATE FOR platform = 'UNIX'
  1090.          IF FOUND()
  1091.             RETURN 'UNIX'
  1092.          ELSE
  1093.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1094.                c_error_2
  1095.          ENDIF
  1096.       ENDIF
  1097.    ENDIF
  1098. ELSE
  1099.    LOCATE FOR platform = IIF(m.g_genvers = 'DOS', 'UNIX', 'DOS')
  1100.    IF FOUND()
  1101.       RETURN platform
  1102.    ELSE
  1103.       LOCATE FOR platform = 'WINDOWS'
  1104.       IF FOUND()
  1105.          RETURN 'DOS'
  1106.       ELSE
  1107.          LOCATE FOR platform = 'MAC'
  1108.          IF FOUND()
  1109.             RETURN 'UNIX'
  1110.          ELSE
  1111.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1112.                c_error_2
  1113.          ENDIF
  1114.       ENDIF
  1115.    ENDIF
  1116. ENDIF
  1117. RETURN ""
  1118.  
  1119.  
  1120. *!*****************************************************************************
  1121. *!
  1122. *!      Procedure: PREPWNAMES
  1123. *!
  1124. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1125. *!
  1126. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  1127. *!               : SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  1128. *!
  1129. *!*****************************************************************************
  1130. PROCEDURE prepwnames
  1131. *)
  1132. *) PREPWNAMES - Store #WNAME directive strings.  They must be in the setup snippet.
  1133. *)
  1134. PARAMETER m.scrnno
  1135. PRIVATE m.lineno, m.textline
  1136. m.lineno = ATCLINE('#WNAM',setupcode)
  1137. IF m.lineno > 0
  1138.    m.textline = MLINE(setupcode,m.lineno)
  1139.    DO killcr WITH m.textline
  1140.    IF g_screens[m.scrnno,6]   && DOS 2.0 screen
  1141.       IF ATC('#WNAM',m.textline) = 1
  1142.          g_wnames[m.scrnno, getplatnum("DOS")] = skipwhitespace(m.textline)
  1143.       ENDIF
  1144.    ELSE
  1145.       IF ATC('#WNAM',m.textline) = 1
  1146.          g_wnames[m.scrnno, getplatnum(platform)] = skipwhitespace(m.textline)
  1147.       ENDIF
  1148.    ENDIF
  1149. ENDIF
  1150. RETURN
  1151.  
  1152. *!*****************************************************************************
  1153. *!
  1154. *!       Function: SCREENUSED
  1155. *!
  1156. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1157. *!
  1158. *!          Calls: ILLEGALNAME()      (function  in GENSCRN.PRG)
  1159. *!
  1160. *!*****************************************************************************
  1161. FUNCTION screenused
  1162. *)
  1163. *) SCREENUSED - Check to see if screen file already opened.
  1164. *)
  1165. PARAMETER m.dbalias, m.fulldbname
  1166. m.dbalias = LEFT(m.dbalias,c_aliaslen)
  1167. IF NOT USED(m.dbalias)
  1168.    IF illegalname(m.dbalias)
  1169.       g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1170.    ELSE
  1171.       g_screens[m.g_nscreens,5] = m.dbalias
  1172.    ENDIF
  1173.    RETURN .F.
  1174. ENDIF
  1175. SELECT (m.dbalias)
  1176. IF RAT(".SCX",DBF())<>0 AND m.fulldbname=DBF()
  1177.    g_screens[m.g_nscreens,5] = m.dbalias
  1178.    RETURN .T.
  1179. ELSE
  1180.    g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1181. ENDIF
  1182. RETURN .F.
  1183.  
  1184. *!*****************************************************************************
  1185. *!
  1186. *!       Function: ILLEGALNAME
  1187. *!
  1188. *!      Called by: SCREENUSED()       (function  in GENSCRN.PRG)
  1189. *!
  1190. *!*****************************************************************************
  1191. FUNCTION illegalname
  1192. *)
  1193. *) ILLEGALNAME - Check if default alias will be used when this
  1194. *)               database is USEd. (i.e., 1st letter is not A-Z,
  1195. *)                a-z or '_', or any one of ramaining letters is not
  1196. *)                alphanumeric.)
  1197. *)
  1198. PARAMETER m.dname
  1199. PRIVATE m.start, m.aschar, m.length
  1200. m.length = LEN(m.dname)
  1201. m.start  = 0
  1202. IF m.length = 1
  1203.    *
  1204.    * If length 1, then check if default alias can be used,
  1205.    * i.e., name is different than A-J and a-j.
  1206.    *
  1207.    m.aschar = ASC(m.dname)
  1208.    IF (m.aschar >= 65 AND m.aschar <= 74) OR ;
  1209.          (m.aschar >= 97 AND m.aschar <= 106)
  1210.       RETURN .T.
  1211.    ENDIF
  1212. ENDIF
  1213. DO WHILE m.start < m.length
  1214.    m.start  = m.start + 1
  1215.    m.aschar = ASC(SUBSTR(m.dname, m.start, 1))
  1216.    IF m.start<>1 AND (m.aschar >= 48 AND m.aschar <= 57)
  1217.       LOOP
  1218.    ENDIF
  1219.    IF NOT ((m.aschar >= 65 AND m.aschar <= 90) OR ;
  1220.          (m.aschar >= 97 AND m.aschar <= 122) OR m.aschar = 95)
  1221.       RETURN .T.
  1222.    ENDIF
  1223. ENDDO
  1224. RETURN .F.
  1225.  
  1226. *!*****************************************************************************
  1227. *!
  1228. *!       Function: OPENPROJDBF
  1229. *!
  1230. *!      Called by: GENSCRN.PRG
  1231. *!
  1232. *!          Calls: NOTEAREA           (procedure in GENSCRN.PRG)
  1233. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  1234. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1235. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  1236. *!               : GETWITHLIST        (procedure in GENSCRN.PRG)
  1237. *!
  1238. *!*****************************************************************************
  1239. FUNCTION openprojdbf
  1240. *)
  1241. *) OPENPROJDBF - Prepare Project dbf for processing.
  1242. *)
  1243. *) Description:
  1244. *) Check to see if projdbf has an appropriate number of fields.
  1245. *) Find the screen set record.
  1246. *) Extract information from the SETID record.
  1247. *)
  1248. PARAMETER m.projdbf, m.recno
  1249.  
  1250. SELECT 0
  1251. IF USED("projdbf")
  1252.    m.g_projalias = "P"+SUBSTR(LOWER(SYS(3)),2,8)
  1253. ELSE
  1254.    m.g_projalias = "projdbf"
  1255. ENDIF
  1256. USE (m.projdbf) ALIAS (m.g_projalias)
  1257. DO notearea
  1258. IF versnum() > "2.5"
  1259.    SET NOCPTRANS TO devinfo, arranged, symbols, object
  1260. ENDIF
  1261. m.g_errlog = stripext(m.projdbf)
  1262. m.g_projpath = SUBSTR(m.projdbf,1,RAT("\",m.projdbf))
  1263.  
  1264. IF FCOUNT() <> c_pjxflds
  1265.    IF FCOUNT() = c_pjx20flds
  1266.       DO errorhandler WITH "Invalid 2.0 project file passed to GenScrn.",;
  1267.          LINENO(), c_error_2
  1268.    ELSE
  1269.       DO errorhandler WITH "Generator out of date.",;
  1270.          LINENO(), c_error_2
  1271.    ENDIF
  1272.    RETURN .F.
  1273. ENDIF
  1274.  
  1275. DO refreshprefs
  1276. GOTO m.recno
  1277. m.g_keyno        = setid
  1278. m.g_outfile      = ALLTRIM(SUBSTR(outfile,1,AT(c_null,outfile)-1))
  1279. m.g_outfile      = FULLPATH(m.g_outfile, m.g_projpath)
  1280. IF RIGHT(m.g_outfile,1) = ":"
  1281.    m.g_outfile = m.g_outfile + justfname(outfile)
  1282. ENDIF
  1283. m.g_openfiles    = openfiles
  1284. m.g_closefiles   = closefiles
  1285. m.g_defwin       = defwinds
  1286. m.g_relwin       = relwinds
  1287. m.g_readcycle    = readcycle
  1288. m.g_readlock     = NOLOCK
  1289. m.g_readmodal    = MODAL
  1290. m.g_readborder   = nologo
  1291. m.g_multreads    = multreads
  1292. m.g_allplatforms = !savecode
  1293. DO getwithlist
  1294. RETURN
  1295.  
  1296. *!*****************************************************************************
  1297. *!
  1298. *!      Procedure: GETWITHLIST
  1299. *!
  1300. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1301. *!
  1302. *!*****************************************************************************
  1303. PROCEDURE getwithlist
  1304. *)
  1305. *) GETWITHLIST - Construct the list for READ level WITH clause.  The
  1306. *) window list is in the project file, stored as CR separated strings
  1307. *) possibly terminated with a NULL.
  1308. *)
  1309.  
  1310. m.g_withlist = assocwinds
  1311. * Drop any nulls
  1312. m.g_withlist = ALLTRIM(CHRTRAN(m.g_withlist, CHR(0), ""))
  1313. * Translate any CRs/LFs into commas
  1314. m.g_withlist = CHRTRAN(m.g_withlist, c_cret+c_lf, ",,")
  1315. * Sanity check for duplicate commas
  1316. m.g_withlist = STRTRAN(m.g_withlist, ",,", ",")   && shouldn't be necessary
  1317. IF RIGHT(m.g_withlist,1) = ","
  1318.    m.g_withlist = LEFT(m.g_withlist, LEN(m.g_withlist) - 1)
  1319. ENDIF
  1320. IF LEFT(m.g_withlist,1) = ","
  1321.    m.g_withlist = RIGHT(m.g_withlist, LEN(m.g_withlist) - 1)
  1322. ENDIF
  1323. RETURN
  1324.  
  1325. *!*****************************************************************************
  1326. *!
  1327. *!      Procedure: REFRESHPREFS
  1328. *!
  1329. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1330. *!
  1331. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1332. *!               : SUBDEVINFO()       (function  in GENSCRN.PRG)
  1333. *!
  1334. *!*****************************************************************************
  1335. PROCEDURE refreshprefs
  1336. *)
  1337. *) REFRESHPREFS - Refresh Documentation and Developer preferences.
  1338. *)
  1339. *) Description:
  1340. *) Get the newest preferences for documentation style and developer
  1341. *) data from the HEADER record.
  1342. *)
  1343. PRIVATE m.start
  1344. LOCATE FOR TYPE = "H"
  1345. IF NOT FOUND ()
  1346.    DO errorhandler WITH "Missing header record in "+m.projdbf,;
  1347.       LINENO(), c_error_2
  1348.    RETURN
  1349. ENDIF
  1350. IF _MAC
  1351.     * On the Mac, the home directory will be stored in homedir unless
  1352.     * it is in a non-DOS format (e.g., contains spaces), in which case
  1353.     * it is stored in the assocwinds field.  This subterfuge is to 
  1354.     * maintain cross platform compatibility of the projects.
  1355.     IF !EMPTY(assocwinds)
  1356.         m.g_homedir = ALLTRIM(SUBSTR(assocwinds,1,AT(c_null,assocwinds)-1))
  1357.     ELSE
  1358.         m.g_homedir = ALLTRIM(SUBSTR(homedir,1,AT(c_null,homedir)-1))
  1359.         IF RIGHT(m.g_homedir,1) <> "\"
  1360.            m.g_homedir = m.g_homedir + "\"
  1361.         ENDIF
  1362.     ENDIF
  1363. ELSE
  1364.     m.g_homedir = ALLTRIM(SUBSTR(homedir,1,AT(c_null,homedir)-1))
  1365.     IF RIGHT(m.g_homedir,1) <> "\"
  1366.        m.g_homedir = m.g_homedir + "\"
  1367.     ENDIF
  1368. ENDIF
  1369.  
  1370. m.start = 1
  1371. m.g_devauthor = subdevinfo(m.start,c_authorlen,m.g_devauthor)
  1372.  
  1373. m.start = m.start + c_authorlen + 1
  1374. m.g_devcompany = subdevinfo(m.start,c_complen,m.g_devcompany)
  1375.  
  1376. m.start = m.start + c_complen + 1
  1377. m.g_devaddress = subdevinfo(m.start,c_addrlen,m.g_devaddress)
  1378.  
  1379. m.start = m.start + c_addrlen + 1
  1380. m.g_devcity = subdevinfo(m.start,c_citylen,m.g_devcity)
  1381.  
  1382. m.start = m.start + c_citylen + 1
  1383. m.g_devstate = subdevinfo(m.start,c_statlen,m.g_devstate)
  1384.  
  1385. m.start = m.start + c_statlen + 1
  1386. m.g_devzip = subdevinfo(m.start,c_ziplen,m.g_devzip)
  1387.  
  1388. m.start = m.start + c_ziplen + 1
  1389. m.g_devctry = subdevinfo(m.start,c_countrylen,m.g_devctry)
  1390.  
  1391. IF cmntstyle = 0
  1392.    m.g_corn1 = "÷"
  1393.    m.g_corn2 = "∑"
  1394.    m.g_corn3 = "”"
  1395.    m.g_corn4 = "Ω"
  1396.    m.g_corn5 = "«"
  1397.    m.g_corn6 = "∂"
  1398.    m.g_horiz = "ƒ"
  1399.    m.g_verti1 = "∫"
  1400.    m.g_verti2= "∫"
  1401. ENDIF
  1402. RETURN
  1403.  
  1404. *!*****************************************************************************
  1405. *!
  1406. *!       Function: SUBDEVINFO
  1407. *!
  1408. *!      Called by: REFRESHPREFS       (procedure in GENSCRN.PRG)
  1409. *!
  1410. *!*****************************************************************************
  1411. FUNCTION subdevinfo
  1412. *)
  1413. *) SUBDEVINFO - Extract strings from the DEVINFO memo field.
  1414. *)
  1415. PARAMETER m.start, m.stop, m.default
  1416. PRIVATE m.string
  1417. m.string = SUBSTR(devinfo, m.start, m.stop+1)
  1418. m.string = SUBSTR(m.string, 1, AT(c_null,m.string)-1)
  1419. RETURN IIF(EMPTY(m.string), m.default, m.string)
  1420.  
  1421. **
  1422. ** High Level Controlling Structures in Format file generation.
  1423. **
  1424.  
  1425. *!*****************************************************************************
  1426. *!
  1427. *!      Procedure: BUILD
  1428. *!
  1429. *!      Called by: GENSCRN.PRG
  1430. *!
  1431. *!          Calls: BUILDENABLE        (procedure in GENSCRN.PRG)
  1432. *!               : ACTTHERM           (procedure in GENSCRN.PRG)
  1433. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1434. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1435. *!               : COMBINE            (procedure in GENSCRN.PRG)
  1436. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  1437. *!               : DEACTTHERMO        (procedure in GENSCRN.PRG)
  1438. *!
  1439. *!*****************************************************************************
  1440. PROCEDURE BUILD
  1441. *)
  1442. *) BUILD - Controlling procedure for building of a format file.
  1443. *)
  1444. *) Description:
  1445. *) This procedure is a controlling procedure for the process of
  1446. *) generating a screen file.  It enables building, activates the
  1447. *) thermometer, calls BUILDCTRL and combines two output files,
  1448. *) and finally disables building.
  1449. *) This procedure also makes calls to UPDTHERM to
  1450. *) update the thermometer display.
  1451. *)
  1452.  
  1453. DO buildenable
  1454. DO acttherm WITH "Generating Screen Code..."
  1455. DO updtherm WITH c_therm1 * m.g_numplatforms     && 5%
  1456.  
  1457. DO dispatchbuild
  1458.  
  1459. DO updtherm WITH c_therm7 * m.g_numplatforms     && 95%
  1460. DO combine
  1461. DO updtherm WITH 100 * m.g_numplatforms   && force thermometer to complete
  1462. DO builddisable
  1463.  
  1464. DO deactthermo
  1465. RETURN
  1466.  
  1467. *!*****************************************************************************
  1468. *!
  1469. *!      Procedure: DISPATCHBUILD
  1470. *!
  1471. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  1472. *!
  1473. *!          Calls: COUNTPLATFORMS     (procedure in GENSCRN.PRG)
  1474. *!               : PREPPARAMS         (procedure in GENSCRN.PRG)
  1475. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1476. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  1477. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1478. *!               : LOOKUPPLATFORM     (procedure in GENSCRN.PRG)
  1479. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1480. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1481. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  1482. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1483. *!               : NEWWINDOWS()       (function  in GENSCRN.PRG)
  1484. *!               : NEWDBFS()          (function  in GENSCRN.PRG)
  1485. *!               : NEWREADCLAUSES     (procedure in GENSCRN.PRG)
  1486. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  1487. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  1488. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  1489. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1490. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  1491. *!
  1492. *!*****************************************************************************
  1493. PROCEDURE dispatchbuild
  1494. *)
  1495. *) DISPATCHBUILD - Determines which platforms are to be generated and
  1496. *)                  calls BUILDCTRL for each one.
  1497. *)
  1498. PRIVATE m.i, m.thisplat, m.j
  1499. m.g_numplatforms = countplatforms()
  1500.  
  1501. DO prepparams
  1502.  
  1503. _TEXT = m.g_orghandle
  1504. _PRETEXT = ""
  1505.  
  1506. DO CASE
  1507. CASE multiplat()
  1508.    * Emit code for all common platforms in the screen set and put CASE statements
  1509.    * around the code for each one.  The g_platforms array contains the list of
  1510.    * platforms to generate for.
  1511.  
  1512.    * If generating for multiple platforms, scan all cleanup snippets and assemble an
  1513.    * array of unique procedure names.  This process is designed to handle procedure name
  1514.    * collisions across platforms.
  1515.    DO scanproc
  1516.  
  1517.    DO header   && main heading at top of program
  1518.  
  1519.    * Special case when there are multiple platforms being sent to the
  1520.    * same SPR.  Since the SPR can only have a single parameter statement,
  1521.    * and since it has to appear before the CASE _platform code, put it
  1522.    * here.
  1523.    DO genparameter
  1524.  
  1525.    m.thisplat = "X"   && placeholder value
  1526.    m.i = 1
  1527.    DO WHILE !EMPTY(m.thisplat)
  1528.       m.thisplat = lookupplatform(m.i)
  1529.       IF !EMPTY(m.thisplat)
  1530.          DO putmsg WITH "Generating code for "+versioncap(m.thisplat, m.g_dualoutput)
  1531.       
  1532.          IF m.i = 1
  1533.             \DO CASE
  1534.          ELSE
  1535.             \
  1536.          ENDIF
  1537.          DO gencasestmt WITH m.thisplat
  1538.          \
  1539.          
  1540.          * Switch the platform to generate for
  1541.          m.g_genvers = m.thisplat
  1542.  
  1543.          * Update screen array entries for the new platform, unless it's the currently
  1544.          * executing platform, in which case we did this just above.
  1545.          IF !(m.thisplat == m.g_thisvers)
  1546.             * Start with a fresh set of screens.  Prepscreens() fills in the details.
  1547.             g_nscreens = 0
  1548.             IF !prepscreens(m.thisplat)
  1549.                DO errorhandler WITH "Error initializing screens for ";
  1550.                   +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1551.                CANCEL
  1552.             ENDIF
  1553.             DO newwindows      && initialize the window array
  1554.             DO newdbfs         && initialize the DBF name array
  1555.             DO newreadclauses  && initialize the read clause variables
  1556.             DO newdirectives   && initialize the directives that change from platform to platform
  1557.             DO newschemes      && initialize the scheme variables
  1558.          ENDIF
  1559.  
  1560.          DO pushindent
  1561.          DO buildctrl WITH m.thisplat, m.i, .F.
  1562.          DO popindent
  1563.       ENDIF
  1564.       m.i = m.i + 1
  1565.    ENDDO
  1566.    \
  1567.    \ENDCASE
  1568.    \
  1569.    _TEXT = m.g_tmphandle
  1570.    m.thispretext = _PRETEXT
  1571.    _PRETEXT = ""
  1572.    DO updtherm WITH c_therm6 * m.g_numplatforms  && 70%
  1573.    DO genprocedures
  1574.    _TEXT = m.g_orghandle
  1575.    _PRETEXT = m.thispretext
  1576.  
  1577. OTHERWISE                         && just outputing one platform.
  1578.    * If we are generating for a platform other than the one we are running
  1579.    * on, run through prepscreens again to assign the right platform
  1580.    * name to each of these screens.
  1581.    IF (_DOS AND g_platforms[1] <> "DOS") ;
  1582.          OR (_WINDOWS AND g_platforms[1] <> "WINDOWS") ;
  1583.          OR (_MAC AND g_platforms[1] <> "MAC") ;
  1584.          OR (_UNIX AND g_platforms[1] <> "UNIX")
  1585.       g_nscreens = 0
  1586.       IF !prepscreens(g_platforms[1])
  1587.          DO errorhandler WITH "Error initializing screens for ";
  1588.             +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1589.          CANCEL
  1590.       ENDIF
  1591.    ENDIF
  1592.  
  1593.    m.g_allplatforms = .F.
  1594.    m.g_numplatforms = 1
  1595.    m.g_genvers      = g_platforms[1]
  1596.  
  1597.    DO newwindows      && Initialize the array of window names
  1598.    DO newdbfs         && Initialize the array of DBF names
  1599.    DO newreadclauses  && Initialize the read clause variables for each platform
  1600.    DO newdirectives   && Initialize the directives that change from platform to platform
  1601.    DO newschemes      && initialize the scheme variables
  1602.  
  1603.    DO header
  1604.    DO buildctrl WITH g_platforms[1], 1, .T.
  1605.  
  1606.    DO updtherm WITH  c_therm6   && 70%
  1607.    DO genprocedures
  1608. ENDCASE
  1609. RETURN
  1610.  
  1611.  
  1612. **
  1613. ** Code Associated With Building of the Control Program.
  1614. **
  1615. *!*****************************************************************************
  1616. *!
  1617. *!      Procedure: BUILDCTRL
  1618. *!
  1619. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1620. *!
  1621. *!          Calls: HEADER             (procedure in GENSCRN.PRG)
  1622. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1623. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  1624. *!               : GENSETENVIRON      (procedure in GENSCRN.PRG)
  1625. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  1626. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1627. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  1628. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  1629. *!               : DEFPOPUPS          (procedure in GENSCRN.PRG)
  1630. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  1631. *!               : GENCLNENVIRON      (procedure in GENSCRN.PRG)
  1632. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  1633. *!
  1634. *!*****************************************************************************
  1635. PROCEDURE buildctrl
  1636. *)
  1637. *) BUILDCTRL - Generate Format control file.
  1638. *)
  1639. *) Description:
  1640. *) Buildctrl controls the generation process.  It invokes procedures
  1641. *) which build the output program from a set of screens.
  1642. *)
  1643. PARAMETERS m.pltfrm, m.pnum, m.putparam, m.dbalias
  1644. PRIVATE m.i
  1645.  
  1646. IF m.putparam
  1647.    * Bracketed code is handled elsewhere.  We are only emitting the parameter
  1648.    * from this platform.  Go get it again to make sure we have the right one.
  1649.    * At this point, g_parameter could contain the parameter from any platform.
  1650.  
  1651.    * Open the database for the first screen since it's the only one we can generate
  1652.    * a parameter statement for.
  1653.    m.dbalias = g_screens[1,5]
  1654.    SELECT (m.dbalias)
  1655.    DO seekheader WITH 1
  1656.  
  1657.    m.g_parameter = getparam("setupcode")
  1658.  
  1659.    DO genparameter
  1660. ENDIF
  1661. DO gensect1                                && SECTION 1 setup code
  1662. DO gensetenviron                        && environment setup code
  1663. IF m.g_openfiles
  1664.    DO genopendbfs                        && USE ... INDEX ... statements
  1665. ENDIF
  1666. DO updtherm WITH thermadj(m.pnum,c_therm2,c_therm5)    && and SET RELATIONS
  1667.  
  1668. DO defwindows                             && window definitions
  1669. DO gensect2                                && SECTION 2 setup code
  1670. DO defpopups                            && lists
  1671. DO updtherm WITH thermadj(m.pnum,c_therm3,c_therm5)
  1672.  
  1673. DO buildfmt WITH m.pnum            && @ ... SAY/GET statements
  1674.  
  1675. DO updtherm WITH thermadj(m.pnum,c_therm4,c_therm5)
  1676. IF m.g_windows AND m.g_relwin AND !m.g_noread
  1677.    * If the READ is omitted, don't produce the code to release the window.
  1678.    FOR m.i = 1 TO m.g_nwindows
  1679.       \RELEASE WINDOW <<g_wndows[m.i,1]>>
  1680.    ENDFOR
  1681. ENDIF
  1682.  
  1683. IF m.g_moddesktop AND m.g_relwin AND INLIST(m.g_genvers,"WINDOWS","MAC")
  1684.    \MODIFY WINDOW SCREEN
  1685. ENDIF
  1686.  
  1687. DO genclnenviron                        && environment cleanup code
  1688. DO updtherm WITH thermadj(m.pnum,c_therm5,c_therm5)
  1689. DO gencleanup                       && cleanup code, but not procedures/functions
  1690.  
  1691. *!*****************************************************************************
  1692. *!
  1693. *!      Procedure: GENSETENVIRON
  1694. *!
  1695. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1696. *!
  1697. *!*****************************************************************************
  1698. PROCEDURE gensetenviron
  1699. *)
  1700. *) GENSETENVIRON - Generate environment code for the .SPR
  1701. *)
  1702. IF !m.g_noreadplain
  1703.    \
  1704.    \#REGION 0
  1705.    \REGIONAL m.currarea, m.talkstat, m.compstat
  1706.    \
  1707.    \IF SET("TALK") = "ON"
  1708.    \    SET TALK OFF
  1709.    \    m.talkstat = "ON"
  1710.    \ELSE
  1711.    \    m.talkstat = "OFF"
  1712.    \ENDIF
  1713.    \m.compstat = SET("COMPATIBLE")
  1714.    \SET COMPATIBLE FOXPLUS
  1715.    
  1716.    IF INLIST(m.g_genvers,"WINDOWS","MAC")
  1717.       \
  1718.       \m.rborder = SET("READBORDER")
  1719.       \SET READBORDER <<IIF(m.g_readborder, "ON", "OFF")>>
  1720.    ENDIF
  1721. ENDIF   
  1722.  
  1723. IF m.g_closefiles
  1724.    \
  1725.    \m.currarea = SELECT()
  1726.    \
  1727. ENDIF
  1728. RETURN
  1729.  
  1730. *!*****************************************************************************
  1731. *!
  1732. *!      Procedure: GENCLNENVIRON
  1733. *!
  1734. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1735. *!
  1736. *!          Calls: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  1737. *!               : RELPOPUPS          (procedure in GENSCRN.PRG)
  1738. *!
  1739. *!*****************************************************************************
  1740. PROCEDURE genclnenviron
  1741. *)
  1742. *) GENCLNENVIRON - Generate environment code for the .SPR
  1743. *)
  1744. IF m.g_closefiles
  1745.    DO genclosedbfs
  1746. ENDIF
  1747. IF m.g_somepops
  1748.    DO relpopups
  1749. ENDIF
  1750. IF !m.g_noreadplain
  1751.    \
  1752.    \#REGION 0
  1753.    IF INLIST(m.g_genvers,"WINDOWS","MAC")
  1754.       \
  1755.       \SET READBORDER &rborder
  1756.       \
  1757.    ENDIF
  1758.    \IF m.talkstat = "ON"
  1759.    \    SET TALK ON
  1760.    \ENDIF
  1761.    \IF m.compstat = "ON"
  1762.    \    SET COMPATIBLE ON
  1763.    \ENDIF
  1764.    \
  1765. ENDIF
  1766. RETURN
  1767.  
  1768. *!*****************************************************************************
  1769. *!
  1770. *!      Procedure: GENCLEANUP
  1771. *!
  1772. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1773. *!
  1774. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  1775. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1776. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1777. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1778. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  1779. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  1780. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1781. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1782. *!
  1783. *!*****************************************************************************
  1784. PROCEDURE gencleanup
  1785. *)
  1786. *) GENCLEANUP - Generate Cleanup Code.
  1787. *)
  1788. PRIVATE m.i, m.dbalias, m.msg
  1789.  
  1790. IF m.g_graphic
  1791.    m.msg = 'Generating Cleanup Code'
  1792.    IF multiplat()
  1793.       m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  1794.    ENDIF
  1795.    DO putmsg WITH  m.msg
  1796. ENDIF
  1797.  
  1798. * Generate the actual cleanup code--the code that precedes procedures
  1799. * and function declarations.
  1800. FOR m.i = 1 TO m.g_nscreens
  1801.    m.g_screen = m.i
  1802.    m.dbalias = g_screens[m.i,5]
  1803.    SELECT (m.dbalias)
  1804.  
  1805.    DO seekheader WITH m.i
  1806.    IF EMPTY (proccode)
  1807.       g_firstproc[m.i] = 0
  1808.       LOOP
  1809.    ENDIF
  1810.  
  1811.    * Find the line number where the first procedure or function
  1812.    * declaration occurs
  1813.    g_firstproc[m.i] = getfirstproc("PROCCODE")
  1814.  
  1815.    IF g_firstproc[m.i] <> 1
  1816.       * Either there aren't any procedures/functions, or they
  1817.       * are below the actual cleanup code.  Emit the cleanup code.
  1818.       DO commentblock WITH g_screens[m.i,1], " Cleanup Code"
  1819.       \#REGION <<INT(m.i)>>
  1820.       DO writecode WITH proccode, getplatname(m.i), c_fromone, g_firstproc[m.i], m.i
  1821.    ENDIF
  1822. ENDFOR
  1823. m.g_screen = 0
  1824.  
  1825. RETURN
  1826.  
  1827. *!*****************************************************************************
  1828. *!
  1829. *!      Procedure: GENPROCEDURES
  1830. *!
  1831. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1832. *!
  1833. *!          Calls: PUTMSG             (procedure in GENSCRN.PRG)
  1834. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1835. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  1836. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1837. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1838. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1839. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  1840. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  1841. *!
  1842. *!*****************************************************************************
  1843. PROCEDURE genprocedures
  1844. *)
  1845. *) GENPROCEDURES - Generate Procedures and Functions from cleanup code.
  1846. *)
  1847. PRIVATE m.i, m.dbalias
  1848. m.msg = 'Generating Procedures and Functions'
  1849. DO putmsg WITH m.msg
  1850.  
  1851. * Go back through each of the screens and output any procedures and
  1852. * functions that are in the cleanup snippet.
  1853. FOR m.i = 1 TO m.g_nscreens
  1854.    m.g_screen = m.i
  1855.    m.g_isfirstproc = .T.  && reset this for each screen
  1856.    m.dbalias = g_screens[m.i,5]
  1857.    SELECT (m.dbalias)
  1858.    DO seekheader WITH m.i
  1859.  
  1860.    DO CASE
  1861.    CASE g_screens[m.i,6]    && DOS 2.0 screen
  1862.       IF g_firstproc[m.i] > 0
  1863.          DO putprochead WITH m.i, g_screens[m.i,1]
  1864.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1865.       ENDIF
  1866.    CASE multiplat()
  1867.       * Multiple 2.5 platforms
  1868.       IF m.g_procsmatch   && all cleanup snippets in the file are the same
  1869.          * Get all the screen/platform headers from this screen file
  1870.          IF g_firstproc[m.i] > 0
  1871.             DO putprochead WITH m.i, g_screens[m.i,1]
  1872.             DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1873.          ENDIF
  1874.       ELSE
  1875.          * The are some differences.  Look for procedure name collisions among the
  1876.          * cleanup snippets in the platforms we are generating.
  1877.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  1878.             IF EMPTY(proccode)
  1879.                LOOP
  1880.             ENDIF
  1881.             DO putprochead WITH m.i, g_screens[m.i,1]
  1882.             DO extractprocs WITH m.i
  1883.          ENDSCAN
  1884.       ENDIF
  1885.    OTHERWISE  && just generating one 2.5 platform
  1886.       IF g_firstproc[m.i] > 0
  1887.          DO putprochead WITH m.i, g_screens[m.i,1]
  1888.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1889.       ENDIF
  1890.    ENDCASE
  1891. ENDFOR
  1892. m.g_screen = 0
  1893. RETURN
  1894.  
  1895. *!*****************************************************************************
  1896. *!
  1897. *!       Function: PROCSMATCH
  1898. *!
  1899. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  1900. *!
  1901. *!          Calls: ISGENPLAT()        (function  in GENSCRN.PRG)
  1902. *!
  1903. *!*****************************************************************************
  1904. FUNCTION procsmatch
  1905. *)
  1906. *) PROCSMATCH - Are the CRCs for the cleanup snippets the same for all platforms in the
  1907. *)                current screen that are being generated?
  1908. *)
  1909. PRIVATE m.crccode, m.thiscode, m.in_rec
  1910.  
  1911. m.in_rec = IIF(!EOF(),RECNO(),1)
  1912. m.crccode = "0"
  1913. * Get the headers for all the platforms we are generating
  1914. SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  1915.    m.thiscode = ALLTRIM(SYS(2007,proccode))
  1916.    DO CASE
  1917.    CASE m.crccode = "0"
  1918.       m.crccode = m.thiscode
  1919.    CASE m.thiscode <> m.crccode AND m.crccode <> "0"
  1920.       RETURN .F.
  1921.    ENDCASE
  1922. ENDSCAN
  1923. GOTO m.in_rec
  1924. RETURN .T.
  1925.  
  1926. *!*****************************************************************************
  1927. *!
  1928. *!       Function: ISGENPLAT
  1929. *!
  1930. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  1931. *!               : PROCSMATCH()       (function  in GENSCRN.PRG)
  1932. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  1933. *!
  1934. *!*****************************************************************************
  1935. FUNCTION isgenplat
  1936. *)
  1937. *) ISGENPLAT - Is this platform one of the ones being generated?
  1938. *)
  1939. PARAMETER m.platname
  1940. RETURN IIF(ASCAN(g_platforms,ALLTRIM(UPPER(m.platname))) > 0, .T. , .F. )
  1941.  
  1942. *!*****************************************************************************
  1943. *!
  1944. *!      Procedure: PUTPROCHEAD
  1945. *!
  1946. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  1947. *!
  1948. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  1949. *!
  1950. *!*****************************************************************************
  1951. PROCEDURE putprochead
  1952. *)
  1953. *) PUTPROCHEAD - Emit the procedure and function heading if we haven't done
  1954. *)
  1955. PARAMETER m.scrnno, m.filname
  1956. IF m.g_isfirstproc
  1957.    \
  1958.    DO commentblock WITH g_screens[m.scrnno,1], " Supporting Procedures and Functions "
  1959.    \#REGION <<INT(m.scrnno)>>
  1960.    m.g_isfirstproc = .F.
  1961. ENDIF
  1962. RETURN
  1963.  
  1964. *!*****************************************************************************
  1965. *!
  1966. *!      Procedure: EXTRACTPROCS
  1967. *!
  1968. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  1969. *!
  1970. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  1971. *!               : MATCH()            (function  in GENSCRN.PRG)
  1972. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  1973. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  1974. *!               : HASCONFLICT()      (function  in GENSCRN.PRG)
  1975. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1976. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1977. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  1978. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  1979. *!
  1980. *!*****************************************************************************
  1981. PROCEDURE extractprocs
  1982. *)
  1983. *) EXTRACTPROCS - Output the procedures for the current platform in the current screen
  1984. *)
  1985. * We only get here if we are emitting for multiple platforms and the cleanup snippets
  1986. * for all platforms are not identical.  We are positioned on a screen header record for
  1987. * the g_genvers platform.
  1988. PARAMETER m.scrnno
  1989.  
  1990. PRIVATE m.hascontin, m.iscontin, m.sniplen, m.i, m.thisline, m.pnum, m.word1, m.word2
  1991.  
  1992. _MLINE = 0
  1993. m.sniplen   = LEN(proccode)
  1994. m.numlines  = MEMLINES(proccode)
  1995. m.hascontin = .F.
  1996. DO WHILE _MLINE < m.sniplen
  1997.    m.thisline  = UPPER(ALLTRIM(MLINE(proccode,1, _MLINE)))
  1998.    DO killcr WITH m.thisline
  1999.    m.iscontin  = m.hascontin
  2000.    m.hascontin = RIGHT(m.thisline,1) = ';'
  2001.    IF LEFT(m.thisline,1) $ "PF" AND !m.iscontin
  2002.       m.word1 = wordnum(m.thisline, 1)
  2003.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2004.          m.word2 = wordnum(m.thisline,2)
  2005.          * Does this procedure have a name conflict?
  2006.          m.pnum = getprocnum(m.word2)
  2007.          IF pnum > 0
  2008.             DO CASE
  2009.             CASE g_procs[m.pnum,C_MAXPLATFORMS+2]
  2010.                * This one has already been generated.  Skip past it now.
  2011.                DO emitproc WITH .F., m.thisline, m.sniplen, m.scrnno
  2012.                LOOP
  2013.             CASE hasconflict(pnum)
  2014.                * Name collision detected.  Output bracketed code for all platforms
  2015.                DO putmsg WITH "Generating code for procedure/function ";
  2016.                   +LOWER(g_procs[m.pnum,1])
  2017.                DO updtherm WITH thermadj(m.pnum,c_therm6 + (c_therm7-c_therm6)/m.g_procnames,c_therm7)
  2018.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2019.                   +" " + g_procs[m.pnum,1]
  2020.                DO emitbracket WITH m.pnum, m.scrnno
  2021.             OTHERWISE
  2022.                * This procedure has no name collision and has not been emitted yet.
  2023.                DO putmsg WITH "Generating code for procedure/function ";
  2024.                   +LOWER(g_procs[m.pnum,1])
  2025.                DO updtherm WITH thermadj(m.pnum,c_therm6 + (c_therm7-c_therm6)/m.g_procnames,c_therm7)
  2026.                *DO updtherm WITH (c_therm6 + ((c_therm7-c_therm6)/g_procnames) * m.pnum) * m.g_numplatforms
  2027.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2028.                   +" " + g_procs[m.pnum,1]
  2029.                DO emitproc WITH .T., m.thisline, m.sniplen, m.scrnno
  2030.             ENDCASE
  2031.             g_procs[pnum,C_MAXPLATFORMS+2] = .T.
  2032.          ENDIF
  2033.       ENDIF
  2034.    ENDIF
  2035. ENDDO
  2036. RETURN
  2037.  
  2038. *!*****************************************************************************
  2039. *!
  2040. *!      Procedure: EMITPROC
  2041. *!
  2042. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2043. *!
  2044. *!          Calls: WRITELINE          (procedure in GENSCRN.PRG)
  2045. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2046. *!               : MATCH()            (function  in GENSCRN.PRG)
  2047. *!
  2048. *!*****************************************************************************
  2049. PROCEDURE emitproc
  2050. *)
  2051. *) EMITPROC - Scan through the next procedure/function in the current cleanup snippet.
  2052. *)            If dowrite is TRUE, emit the code as we go.  Otherwise, just skip over it
  2053. *)            and advance _MLINE.
  2054. *)
  2055. * We are positioned on the PROCEDURE or FUNCTION line now and there isn't a name
  2056. * conflict.
  2057. PARAMETER m.dowrite, m.thisline, m.sniplen, m.scrnno
  2058. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2059.    m.iscontin, m.hascontin, m.platnum
  2060.    
  2061. m.hascontin = .F.
  2062. m.done = .F.
  2063.  
  2064. * Write the PROCEDURE/FUNCTION statement
  2065. m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2066.  
  2067. IF g_screens[m.scrnno,6]   && DOS 2.0 screen
  2068.    m.platnum = getplatnum("DOS")
  2069. ELSE
  2070.    m.platnum = getplatnum(m.g_genvers)
  2071. ENDIF
  2072.  
  2073. IF m.dowrite    && actually emit the procedure?
  2074.    DO writeline WITH m.thisline, m.g_genvers, m.platnum, m.upline, m.scrnno
  2075. ENDIF
  2076.  
  2077. * Write the body of the procedure
  2078. DO WHILE !m.done AND _MLINE < m.sniplen
  2079.    m.lastmline = _MLINE          && note where this line started
  2080.  
  2081.    m.line = MLINE(proccode,1, _MLINE)
  2082.    DO killcr WITH m.line
  2083.    m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2084.  
  2085.    m.iscontin = m.hascontin
  2086.    m.hascontin = RIGHT(m.upline,1) = ';'
  2087.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2088.       m.word1 = wordnum(m.upline, 1)
  2089.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2090.          done = .T.
  2091.          _MLINE = m.lastmline    && drop back one line and stop writing
  2092.          LOOP
  2093.       ENDIF
  2094.    ENDIF
  2095.  
  2096.    IF m.dowrite    && actually emit the procedure?
  2097.       DO writeline WITH m.line, m.g_genvers, m.platnum, m.upline, m.scrnno
  2098.    ENDIF
  2099.  
  2100. ENDDO
  2101. RETURN
  2102.  
  2103. *!*****************************************************************************
  2104. *!
  2105. *!      Procedure: EMITBRACKET
  2106. *!
  2107. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2108. *!
  2109. *!          Calls: PUSHINDENT         (procedure in GENSCRN.PRG)
  2110. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2111. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  2112. *!
  2113. *!*****************************************************************************
  2114. PROCEDURE emitbracket
  2115. *)
  2116. *) EMITBRACKET - Emit DO CASE/CASE _DOS brackets and call putproc to emit code for this procedure
  2117. *)
  2118. PARAMETER m.pnum, m.scrnno
  2119. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2120.    m.iscontin, m.hascontin, m.i
  2121. m.hascontin = .F.
  2122. m.done = .F.
  2123. \
  2124. \PROCEDURE <<g_procs[m.pnum,1]>>
  2125. IF !EMPTY(g_procs[m.pnum,C_MAXPLATFORMS+3])
  2126.    \PARAMETERS <<g_procs[m.pnum,C_MAXPLATFORMS+3]>>
  2127. ENDIF
  2128. \DO CASE
  2129.  
  2130. * Peek ahead and get the parameter statement
  2131. FOR m.platnum = 1 TO c_maxplatforms
  2132.    IF g_procs[m.pnum,m.platnum+1] < 0
  2133.       * There was no procedure for this platform
  2134.       LOOP
  2135.    ENDIF
  2136.    \CASE <<"_"+g_platlist[m.platnum]>>
  2137.    DO pushindent
  2138.    DO putproc WITH m.platnum, m.pnum, m.scrnno
  2139.    DO popindent
  2140. ENDFOR
  2141. \ENDCASE
  2142. RETURN
  2143.  
  2144. *!*****************************************************************************
  2145. *!
  2146. *!      Procedure: PUTPROC
  2147. *!
  2148. *!      Called by: EMITBRACKET        (procedure in GENSCRN.PRG)
  2149. *!
  2150. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2151. *!               : MATCH()            (function  in GENSCRN.PRG)
  2152. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2153. *!
  2154. *!*****************************************************************************
  2155. PROCEDURE putproc
  2156. *)
  2157. *) PUTPROC - Write actual code for procedure procnum in platform platnum
  2158. *)
  2159. PARAMETER m.platnum, m.procnum, m.scrnno
  2160. PRIVATE m.in_rec, m.oldmine, m.done, m.line, m.upline, m.iscontin, m.hascontin, ;
  2161.    m.word1, m.word2, m.platnum
  2162.  
  2163. m.in_rec    = RECNO()
  2164. * Store the _MLINE position in the original snippet
  2165. m.oldmline  = _MLINE
  2166. m.hascontin = .F.       && the previous line was not a continuation line.
  2167. LOCATE FOR platform = g_platlist[m.platnum] AND objtype = c_otscreen
  2168. IF FOUND()
  2169.    * go to the PROCEDURE/FUNCTION statement
  2170.    _MLINE = g_procs[m.procnum,m.platnum+1]
  2171.    * Skip the PROCEDURE line, since we've already output one.
  2172.    m.line = MLINE(proccode,1, _MLINE)
  2173.    DO killcr WITH m.line
  2174.  
  2175.    * We are now positioned at the line following the procedure statement.
  2176.    * Write until the end of the snippet or the next procedure.
  2177.    m.done = .F.
  2178.    DO WHILE !m.done
  2179.       m.line = MLINE(proccode,1, _MLINE)
  2180.       DO killcr WITH m.line
  2181.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2182.       m.iscontin = m.hascontin
  2183.       m.hascontin = RIGHT(m.upline,1) = ';'
  2184.       IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2185.          m.word1 = wordnum(m.upline, 1)
  2186.          IF RIGHT(m.word1,1) = ';'
  2187.             m.word1 = LEFT(m.word1,LEN(m.word1)-1)
  2188.          ENDIF
  2189.  
  2190.          DO CASE
  2191.          CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2192.             * Stop when we encounter the next snippet
  2193.             m.done = .T.
  2194.             LOOP
  2195.          CASE match(m.word1,"PARAMETERS")
  2196.             * Don't output it, but keep scanning for other code
  2197.             DO WHILE m.hascontin
  2198.                m.line = MLINE(proccode,1, _MLINE)
  2199.                DO killcr WITH m.line
  2200.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2201.                m.hascontin = RIGHT(m.upline,1) = ';'
  2202.             ENDDO
  2203.             LOOP
  2204.          ENDCASE
  2205.       ENDIF
  2206.  
  2207.       DO writeline WITH m.line, g_platlist[m.platnum], m.platnum, m.upline, m.scrnno
  2208.  
  2209.       * Stop if we've run out of snippet
  2210.       IF _MLINE >= LEN(proccode)
  2211.          m.done = .T.
  2212.       ENDIF
  2213.    ENDDO
  2214. ENDIF
  2215.  
  2216. GOTO m.in_rec
  2217. * Restore the _MLINE position in the main snippet we are outputing
  2218. _MLINE = m.oldmline
  2219. RETURN
  2220.  
  2221. *!*****************************************************************************
  2222. *!
  2223. *!       Function: GETPROCNUM
  2224. *!
  2225. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2226. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2227. *!
  2228. *!*****************************************************************************
  2229. FUNCTION getprocnum
  2230. *)
  2231. *) GETPROCNUM - Return the g_procs array position of the procedure named pname
  2232. *)
  2233. PARAMETER m.pname
  2234. PRIVATE m.i
  2235. FOR m.i = 1 TO g_procnames
  2236.    IF g_procs[m.i,1] == m.pname
  2237.       RETURN m.i
  2238.    ENDIF
  2239. ENDFOR
  2240. RETURN  0
  2241.  
  2242. *!*****************************************************************************
  2243. *!
  2244. *!       Function: HASCONFLICT
  2245. *!
  2246. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2247. *!
  2248. *!*****************************************************************************
  2249. FUNCTION hasconflict
  2250. *)
  2251. *) HASCONFLICT - Is there a name collision for procedure number num?
  2252. *)
  2253. PARAMETER m.num
  2254. PRIVATE m.i, m.cnt
  2255. m.cnt = 0
  2256. FOR m.i = 1 TO c_maxplatforms
  2257.    IF g_procs[m.num,m.i+1] > 0
  2258.       m.cnt = m.cnt +1
  2259.    ENDIF
  2260. ENDFOR
  2261. RETURN IIF(m.cnt > 1,.T.,.F.)
  2262.  
  2263.  
  2264. *!*****************************************************************************
  2265. *!
  2266. *!       Function: GETFIRSTPROC
  2267. *!
  2268. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2269. *!
  2270. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2271. *!               : MATCH()            (function  in GENSCRN.PRG)
  2272. *!
  2273. *!*****************************************************************************
  2274. FUNCTION getfirstproc
  2275. *)
  2276. *) GETFIRSTPROC - Find first PROCEDURE or FUNCTION statement in a cleanup
  2277. *)                snippet and return the line number on which it occurs.
  2278. *)
  2279. PARAMETER m.snipname
  2280. PRIVATE proclineno, numlines, word1, first_space
  2281. _MLINE = 0
  2282. m.numlines = MEMLINES(&snipname)
  2283. FOR m.proclineno = 1 TO m.numlines
  2284.    m.line  = MLINE(&snipname, 1, _MLINE)
  2285.    DO killcr WITH m.line
  2286.    m.line  = UPPER(LTRIM(m.line))
  2287.    m.word1 = wordnum(m.line,1)
  2288.    IF !EMPTY(m.word1) AND (match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION"))
  2289.       RETURN m.proclineno
  2290.    ENDIF
  2291. ENDFOR
  2292. RETURN 0
  2293.  
  2294. *!*****************************************************************************
  2295. *!
  2296. *!      Procedure: SCANPROC
  2297. *!
  2298. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2299. *!
  2300. *!          Calls: PROCSMATCH()       (function  in GENSCRN.PRG)
  2301. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  2302. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2303. *!
  2304. *!*****************************************************************************
  2305. PROCEDURE scanproc
  2306. *)
  2307. *) SCANPROC - Find unique procedure names in cleanup snippets for all platforms
  2308. *)
  2309. PRIVATE m.in_rec
  2310. * See if all the cleanup snippets are the same.  If so, stop now.
  2311. m.g_procsmatch = .T.
  2312. FOR m.g_screen = 1 TO m.g_nscreens
  2313.    m.dbalias = g_screens[m.g_screen,5]
  2314.    SELECT (m.dbalias)
  2315.    IF !g_screens[m.g_screen,6]      && not applicable for FoxPro 2.0 screens
  2316.       m.g_procsmatch = m.g_procsmatch AND procsmatch()
  2317.     ENDIF
  2318. ENDFOR
  2319.  
  2320. IF !m.g_procsmatch
  2321.    FOR m.g_screen = 1 TO m.g_nscreens
  2322.       m.dbalias = g_screens[m.g_screen,5]
  2323.       SELECT (m.dbalias)
  2324.  
  2325.       IF !g_screens[m.g_screen,6]      && not applicable for FoxPro 2.0 screens
  2326.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  2327.             DO updprocarray
  2328.          ENDSCAN
  2329.       ENDIF
  2330.    ENDFOR
  2331.    m.g_screen = 0
  2332. ENDIF
  2333. RETURN
  2334.  
  2335. *!*****************************************************************************
  2336. *!
  2337. *!      Procedure: UPDPROCARRAY
  2338. *!
  2339. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  2340. *!
  2341. *!          Calls: VERSIONCAP()       (function  in GENSCRN.PRG)
  2342. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2343. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2344. *!               : MATCH()            (function  in GENSCRN.PRG)
  2345. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2346. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2347. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  2348. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  2349. *!
  2350. *!*****************************************************************************
  2351. PROCEDURE updprocarray
  2352. *)
  2353. *) UPDPROCARRAY - Pick out the procedures names in the current cleanup snippet and call
  2354. *)                  AddProcName to update the g_procs array.
  2355. *)
  2356. PRIVATE m.i, m.numlines, m.line, m.upline, m.word1, m.word2, m.iscontin, m.hascontin, ;
  2357.    m.lastmline, m.thisproc
  2358.  
  2359. DO putmsg WITH "Scanning cleanup snippet for ";
  2360.    +versioncap( IIF(TYPE("platform")<>"U",platform,"DOS"), m.g_dualoutput )
  2361.  
  2362. _MLINE = 0
  2363. m.numlines = MEMLINES(proccode)
  2364. m.hascontin = .F.
  2365. FOR m.i = 1 TO m.numlines
  2366.    m.lastmline = _MLINE                && note starting position of this line
  2367.    m.line      = MLINE(proccode,1, _MLINE)
  2368.    DO killcr WITH m.line
  2369.    m.upline    = UPPER(ALLTRIM(m.line))
  2370.    m.iscontin  = m.hascontin
  2371.    m.hascontin = RIGHT(m.upline,1) = ';'
  2372.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2373.       m.word1 = CHRTRAN(wordnum(m.upline, 1),';','')
  2374.       DO CASE
  2375.       CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2376.          m.word2 = wordnum(m.upline,2)
  2377.          DO addprocname WITH m.word2, platform, m.i, m.lastmline
  2378.          m.lastproc = m.word2
  2379.       CASE match(m.word1,"PARAMETERS")
  2380.          * Associate this parameter statement with the last procedure or function
  2381.          m.thisproc = getprocnum(m.lastproc)
  2382.          IF m.thisproc > 0
  2383.             m.thisparam = ALLTRIM(SUBSTR(m.upline,AT(' ',m.upline)+1))
  2384.             * Deal with continued PARAMETER lines
  2385.             DO WHILE m.hascontin AND m.i <= m.numlines
  2386.                m.lastmline = _MLINE                && note the starting position of this line
  2387.                m.line   = MLINE(proccode,1, _MLINE)
  2388.                DO killcr WITH m.line
  2389.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2390.                m.thisparam = ;
  2391.                   m.thisparam + CHR(13)+CHR(10) + m.line
  2392.                m.hascontin = RIGHT(m.upline,1) = ';'
  2393.                m.i = m.i + 1
  2394.             ENDDO
  2395.             * Make sure that this parameter matches any others we've seen for this function
  2396.             DO CASE
  2397.             CASE EMPTY(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2398.                * First occurrence, or one platform has a parameter statement and another doesn't
  2399.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2400.             CASE cleanparam(m.thisparam) == cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2401.                * It matches--do nothing
  2402.             CASE cleanparam(m.thisparam) = cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2403.                * The new one is a superset of the existing one.  Use the longer one.
  2404.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2405.             CASE cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3]) = cleanparam(m.thisparam)
  2406.                * The old one is a superset of the new one.  Keep the longer one.
  2407.             OTHERWISE
  2408.                DO errorhandler WITH "Different parameters for "+g_procs[m.thisproc,1],;
  2409.                   LINENO(),c_error_3
  2410.             ENDCASE
  2411.          ENDIF
  2412.       ENDCASE
  2413.    ENDIF
  2414. ENDFOR
  2415. RETURN
  2416.  
  2417. *!*****************************************************************************
  2418. *!
  2419. *!      Procedure: ADDPROCNAME
  2420. *!
  2421. *!      Called by: UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2422. *!
  2423. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2424. *!
  2425. *!*****************************************************************************
  2426. PROCEDURE addprocname
  2427. *)
  2428. *) ADDPROCNAME - Update g_procs with pname data
  2429. *)
  2430. PARAMETER m.pname, m.platname, m.linenum, m.lastmline
  2431. PRIVATE m.rnum, m.platformcol, m.i, m.j
  2432. IF EMPTY(m.pname)
  2433.    RETURN
  2434. ENDIF
  2435.  
  2436. * Look up this name in the procedures array
  2437. m.rnum = 0
  2438. FOR m.i = 1 TO m.g_procnames
  2439.    IF g_procs[m.i,1] == m.pname
  2440.       m.rnum = m.i
  2441.       EXIT
  2442.    ENDIF
  2443. ENDFOR
  2444.  
  2445. IF m.rnum = 0
  2446.    * New name
  2447.    g_procnames = m.g_procnames + 1
  2448.    DIMENSION g_procs[m.g_procnames,C_MAXPLATFORMS+3]
  2449.    g_procs[m.g_procnames,1] = UPPER(ALLTRIM(m.pname))
  2450.    FOR m.j = 1 TO c_maxplatforms
  2451.       g_procs[m.g_procnames,m.j + 1] = -1
  2452.    ENDFOR
  2453.    g_procs[m.g_procnames,C_MAXPLATFORMS+2] = .F.   && not emitted yet
  2454.    g_procs[m.g_procnames,C_MAXPLATFORMS+3] = ""    && parameter statement
  2455.    m.rnum = m.g_procnames
  2456. ENDIF
  2457.  
  2458. m.platformcol = getplatnum(m.platname) + 1
  2459. IF m.platformcol > 1
  2460.    g_procs[m.rnum, m.platformcol] = m.lastmline
  2461. ENDIF
  2462. RETURN
  2463.  
  2464. *!*****************************************************************************
  2465. *!
  2466. *!       Function: GETPLATNUM
  2467. *!
  2468. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  2469. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2470. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2471. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2472. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  2473. *!
  2474. *!*****************************************************************************
  2475. FUNCTION getplatnum
  2476. *)
  2477. *) GETPLATNUM - Return the g_platlist array index given a platform name
  2478. *)
  2479. PARAMETER m.platname
  2480. PRIVATE m.i
  2481. FOR m.i = 1 TO c_maxplatforms
  2482.    IF g_platlist[m.i] == UPPER(ALLTRIM(m.platname))
  2483.       RETURN m.i
  2484.    ENDIF
  2485. ENDFOR
  2486. RETURN 0
  2487.  
  2488. *!*****************************************************************************
  2489. *!
  2490. *!      Procedure: GENCASESTMT
  2491. *!
  2492. *!*****************************************************************************
  2493. PROCEDURE gencasestmt
  2494. *)
  2495. *) GENCASESTMT - Generate the CASE ... statement
  2496. *)
  2497. PARAMETER m.thisplat
  2498. DO CASE
  2499. CASE m.thisplat = "WINDOWS" and !hasrecords("MAC") and hasrecords("WINDOWS")
  2500.    \CASE _WINDOWS OR _MAC   && no MAC records in screen
  2501.     m.g_dualoutput = .T.
  2502. CASE m.thisplat = "MAC" and !hasrecords("WINDOWS") and hasrecords("MAC")
  2503.    \CASE _MAC OR _WINDOWS   && no Windows records in screen
  2504.     m.g_dualoutput = .T.
  2505. CASE m.thisplat = "UNIX" and !hasrecords("DOS") and hasrecords("UNIX")
  2506.    \CASE _UNIX OR _DOS      && no DOS records in screen
  2507.     m.g_dualoutput = .T.
  2508. CASE m.thisplat = "DOS" and !hasrecords("UNIX") and hasrecords("DOS")
  2509.    \CASE _DOS OR _UNIX      && no UNIX records in screen
  2510.     m.g_dualoutput = .T.
  2511. OTHERWISE
  2512.    \CASE _<<m.thisplat>>
  2513.     m.g_dualoutput = .F.
  2514. ENDCASE
  2515. RETURN
  2516.  
  2517. *!*****************************************************************************
  2518. *!
  2519. *!      Procedure: GENPARAMETER
  2520. *!
  2521. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2522. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  2523. *!
  2524. *!*****************************************************************************
  2525. PROCEDURE genparameter
  2526. *)
  2527. *) GENPARAMETER - Generate the PARAMETER statement
  2528. *)
  2529. IF !EMPTY(m.g_parameter)
  2530.    \PARAMETERS <<m.g_parameter>>
  2531. ENDIF
  2532. RETURN
  2533.  
  2534. *!*****************************************************************************
  2535. *!
  2536. *!      Procedure: GENSECT1
  2537. *!
  2538. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2539. *!
  2540. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  2541. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  2542. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2543. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  2544. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2545. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2546. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2547. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2548. *!
  2549. *!*****************************************************************************
  2550. PROCEDURE gensect1
  2551. *)
  2552. *) GENSECT1 - Generate #SECTION 1 code for all screens.
  2553. *)
  2554. PRIVATE m.i, m.dbalias, m.string, m.loop, m.j, m.end, m.msg, m.thisline
  2555. m.msg =  'Generating Setup Code'
  2556. IF multiplat()
  2557.    m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  2558. ENDIF
  2559. DO putmsg WITH m.msg
  2560. m.string = " Setup Code - SECTION 1"
  2561.  
  2562. FOR m.i = 1 TO m.g_nscreens
  2563.    m.g_screen = m.i
  2564.  
  2565.    m.dbalias = g_screens[m.i,5]
  2566.    SELECT (m.dbalias)
  2567.    DO seekheader WITH m.i
  2568.    IF EMPTY (setupcode)
  2569.       LOOP
  2570.    ENDIF
  2571.  
  2572.    m.g_sect1start= c_fromone
  2573.    m.g_sect2start= c_untilend
  2574.    m.loop  = .F.
  2575.  
  2576.    IF ATCLINE("#SECT", setupcode) <> 0
  2577.       m.g_sect1start = findsection(1, setupcode)+1
  2578.       m.g_sect2start = findsection(2, setupcode)
  2579.    ENDIF
  2580.    
  2581.    DO notedirectives WITH (m.i)
  2582.  
  2583.    * See if there are nondirective statements in SECTION 1
  2584.    IF m.g_sect2start-m.g_sect1start <= 3
  2585.       IF m.g_sect2start = 0
  2586.          m.end = MEMLINES(setupcode)
  2587.       ELSE
  2588.          m.end = m.g_sect2start-1
  2589.       ENDIF
  2590.       m.loop = .T.
  2591.       m.j = m.g_sect1start
  2592.       DO WHILE m.j <= m.end
  2593.          m.thisline = MLINE(setupcode,m.j)
  2594.          DO killcr WITH m.thisline
  2595.          IF AT('#',m.thisline) <> 1 OR AT('#INSE',m.thisline) = 1
  2596.             m.loop = .F.
  2597.             EXIT
  2598.          ENDIF
  2599.          m.j = m.j + 1
  2600.       ENDDO
  2601.    ENDIF
  2602.    IF m.loop
  2603.       LOOP
  2604.    ENDIF
  2605.    IF NOT (m.g_sect1start=1 OR (m.g_sect1start=m.g_sect2start) OR ;
  2606.          (m.g_sect2start<>0 AND m.g_sect1start>m.g_sect2start))
  2607.  
  2608.       DO commentblock WITH g_screens[m.i,1], m.string
  2609.       \#REGION <<INT(m.i)>>
  2610.       _MLINE = 0
  2611.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect1start, m.g_sect2start, m.i, 'setup'
  2612.    ENDIF
  2613. ENDFOR
  2614. m.g_screen = 0
  2615. RETURN
  2616.  
  2617. *!*****************************************************************************
  2618. *!
  2619. *!      Procedure: GENSECT2
  2620. *!
  2621. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2622. *!
  2623. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  2624. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2625. *!               : NOTEDIRECTIVES     (procedure in GENSCRN.PRG)
  2626. *!               : COUNTDIRECTIVES()  (function  in GENSCRN.PRG)
  2627. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2628. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2629. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2630. *!               
  2631. *!*****************************************************************************
  2632. PROCEDURE gensect2
  2633. *)
  2634. *) GENSECT2 - Generate Setup code #SECTION 2.
  2635. *)
  2636. PRIVATE m.i, m.dbalias, m.string, m.endline, m.srtline, ;
  2637.    m.linecnt, m.lcnt, m.sect1, m.sect2
  2638. m.string = " Setup Code - SECTION 2"
  2639.  
  2640. FOR m.i = 1 TO m.g_nscreens
  2641.    m.g_screen = m.i
  2642.    m.dbalias = g_screens[m.i,5]
  2643.    SELECT (m.dbalias)
  2644.    DO seekheader WITH m.i
  2645.    IF EMPTY (setupcode)
  2646.       LOOP
  2647.    ENDIF
  2648.  
  2649.    m.g_sect1start= c_fromone
  2650.    m.g_sect2start= c_untilend
  2651.    m.loop  = .F.
  2652.  
  2653.    IF ATCLINE("#SECT", setupcode)<>0
  2654.       m.g_sect1start = findsection(1, setupcode)+1
  2655.       m.g_sect2start = findsection(2, setupcode)
  2656.    ENDIF
  2657.  
  2658.    m.sect1 = m.g_sect1start <> 0
  2659.    m.sect2 = m.g_sect2start <> 0
  2660.  
  2661.    DO notedirectives WITH (m.i)
  2662.    m.lcnt = countdirectives(m.sect1, m.sect2, m.i)
  2663.  
  2664.    IF m.g_sect2start = 0 AND m.g_sect1start > 1
  2665.       * No Section2 to emit
  2666.       LOOP
  2667.    ENDIF
  2668.  
  2669.    m.linecnt = MEMLINES(setupcode)
  2670.  
  2671.    IF m.linecnt > m.lcnt AND m.g_sect2start < m.linecnt
  2672.       DO commentblock WITH g_screens[m.i,1], m.string
  2673.       \#REGION <<INT(m.i)>>
  2674.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect2start, c_untilend, m.i, 'setup'
  2675.    ENDIF
  2676. ENDFOR
  2677. m.g_screen = 0
  2678. RETURN
  2679.  
  2680. *!*****************************************************************************
  2681. *!
  2682. *!       Function: COUNTDIRECTIVES
  2683. *!
  2684. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2685. *!
  2686. *!*****************************************************************************
  2687. FUNCTION countdirectives
  2688. *)
  2689. *) COUNTDIRECTIVES - Count directives in setup snippet.
  2690. *)
  2691. *) This function counts the directives in setup.  It is used to figure out if there
  2692. *) are any non-directive statements in the setup snippet.
  2693. PARAMETER m.sect1, m.sect2, m.scrnno
  2694. PRIVATE m.numlines, m.i, m.lcnt, m.thisline, m.upline
  2695. m.lcnt = 0
  2696. IF AT('#',setupcode) > 0
  2697.    * AT test is optimization to avoid processing the snippet when there are no directives
  2698.    m.numlines = MEMLINES(setupcode)
  2699.    _MLINE = 0
  2700.    FOR m.i = 1 TO m.numlines
  2701.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2702.       DO killcr WITH m.thisline
  2703.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2704.       IF LEFT(m.upline,1) = '#' AND !(LEFT(m.upline,5) = "#INSE")
  2705.          m.lcnt = m.lcnt + 1
  2706.       ENDIF
  2707.    ENDFOR
  2708. ENDIF
  2709. RETURN m.lcnt
  2710.  
  2711. *!*****************************************************************************
  2712. *!
  2713. *!      Procedure: NOTEDIRECTIVES
  2714. *!
  2715. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2716. *!
  2717. *!*****************************************************************************
  2718. PROCEDURE notedirectives
  2719. *)
  2720. *) NOTEDIRECTIVES - Check for global directives such as #READCLAUSES, #NOREAD
  2721. *)
  2722. *) This function notes certain directives in the setup snippet and populates various
  2723. *) global variables so that we don't have to keep going back to the snippet to find
  2724. *) things.
  2725. PARAMETERS m.scrnno
  2726. PRIVATE m.numlines, m.i, m.thisline, m.upline
  2727. m.g_noread    = .F.
  2728. m.g_noreadplain = .F.
  2729. IF AT('#',setupcode) > 0
  2730.    * AT test is optimization to avoid processing the snippet when there are no directives
  2731.    m.numlines = MEMLINES(setupcode)
  2732.    _MLINE = 0
  2733.    FOR m.i = 1 TO m.numlines
  2734.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2735.       DO killcr WITH m.thisline
  2736.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2737.       IF LEFT(m.upline,1) = '#'
  2738.          DO CASE
  2739.          CASE LEFT(m.upline,5) = "#READ"   && #READCLAUSES - Additional READ clauses
  2740.             IF m.g_rddir = .F.
  2741.                m.g_rddir = .T.
  2742.                m.g_rddirno = m.scrnno
  2743.             ENDIF
  2744.          CASE LEFT(m.upline,5) = "#NORE"   && #NOREAD - omit the READ statement
  2745.             m.g_noread = .T.
  2746.             IF AT(m.g_dblampersand,m.upline) > 0
  2747.                m.upline = LEFT(m.upline,AT(m.g_dblampersand,m.upline)-1)
  2748.             ENDIF 
  2749.             m.g_noreadplain = IIF(ATC(' PLAI',m.upline) > 0,.T.,.F.)
  2750.             IF m.g_noreadplain
  2751.                 m.g_openfiles    = .F.
  2752.                     m.g_closefiles   = .F.
  2753.                     m.g_defwin       = .F.
  2754.                     m.g_relwin       = .F.
  2755.             ENDIF
  2756.          ENDCASE
  2757.       ENDIF
  2758.    ENDFOR
  2759. ENDIF
  2760. RETURN
  2761.  
  2762. *!*****************************************************************************
  2763. *!
  2764. *!       Function: FINDSECTION
  2765. *!
  2766. *!      Called by: GENSECT1           (procedure in GENSCRN.PRG)
  2767. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2768. *!
  2769. *!*****************************************************************************
  2770. FUNCTION findsection
  2771. *)
  2772. *) FINDSECTION - Find #SECT... directive.
  2773. *)
  2774. *) Description:
  2775. *) Locate and return the line on which the generator directive '#SECT'
  2776. *) is located on.  If no valid directive found, return 0.
  2777. *)
  2778. PARAMETER m.sectionid, m.memo
  2779. PRIVATE m.line, m.linecnt, m.textline
  2780. m.line    = ATCLINE("#SECT", m.memo)
  2781. m.linecnt = MEMLINE(m.memo)
  2782. DO WHILE m.line <= m.linecnt
  2783.    m.textline = LTRIM(MLINE(m.memo, m.line))
  2784.    DO killcr WITH m.textline
  2785.    IF ATC("#SECT", m.textline)=1
  2786.       IF m.sectionid = 1
  2787.          IF AT("1", m.textline)<>0
  2788.             m.sect1 = .T.
  2789.             RETURN m.line
  2790.          ELSE
  2791.             RETURN 0
  2792.          ENDIF
  2793.       ELSE
  2794.          IF AT("2", m.textline)<>0
  2795.             m.sect2 = .T.
  2796.             RETURN m.line
  2797.          ENDIF
  2798.       ENDIF
  2799.    ENDIF
  2800.    m.line = m.line + 1
  2801. ENDDO
  2802. RETURN 0
  2803.  
  2804. *!*****************************************************************************
  2805. *!
  2806. *!      Procedure: WRITECODE
  2807. *!
  2808. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2809. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  2810. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  2811. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2812. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  2813. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  2814. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  2815. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  2816. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  2817. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  2818. *!
  2819. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2820. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2821. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  2822. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2823. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2824. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2825. *!               
  2826. *!*****************************************************************************
  2827. PROCEDURE writecode
  2828. *)
  2829. *) WRITECODE - Write contents of a memo to a low level file.
  2830. *)
  2831. *) Description:
  2832. *) Receive a memo field as a parameter and write its contents out
  2833. *) to the currently opened low level file whose handle is stored
  2834. *) in the system memory variable _TEXT.  Contents of the system
  2835. *) memory variable _PRETEXT will affect the positioning of the
  2836. *) generated text.
  2837. *)
  2838. PARAMETER m.memo, m.platname, m.start, m.end, m.scrnno, m.insetup
  2839. PRIVATE m.linecnt, m.i, m.line, m.upline, m.expr, m.platnum, m.at, m.in_exact
  2840.  
  2841. m.in_exact = SET("EXACT")
  2842. SET EXACT OFF
  2843.  
  2844. _MLINE = 0
  2845.  
  2846. m.start = MAX(1,m.start)  && if zero, start at 1
  2847.  
  2848. IF m.end > m.start
  2849.    m.linecnt = m.end-1
  2850. ELSE
  2851.    m.linecnt = MEMLINES(m.memo)
  2852. ENDIF
  2853.  
  2854. m.platnum = getplatnum(m.platname)
  2855.  
  2856. FOR m.i = 1 TO m.start - 1
  2857.    m.line = MLINE(m.memo, 1, _MLINE)
  2858. ENDFOR
  2859.  
  2860. * Window substitution names
  2861. m.subwindname = g_wnames[m.scrnno,m.platnum]
  2862. m.emptysubwind = IIF(EMPTY(m.subwindname),.T.,.F.)
  2863.  
  2864. IF NOT EMPTY(m.insetup)
  2865.    FOR m.i = m.start TO m.linecnt
  2866.       m.line = MLINE(m.memo, 1, _MLINE)
  2867.       DO killcr WITH m.line
  2868.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2869.       IF !geninsertcode(@upline,m.scrnno, m.insetup, m.platname)
  2870.          m.isparam =  isparameter(@upline)
  2871.          DO CASE
  2872.          CASE m.isparam
  2873.             * Accumulate continuation line but don't output it.
  2874.             DO WHILE RIGHT(m.upline,1) = ';'
  2875.                m.line = MLINE(m.memo, 1, _MLINE)
  2876.                m.upline = m.upline + ALLTRIM(UPPER(m.line))
  2877.                m.i = m.i + 1
  2878.             ENDDO
  2879.             DO killcr WITH m.line
  2880.          CASE m.upline = "#"
  2881.                * don't output a generator directive, but #DEFINES are OK
  2882.                IF LEFT(m.upline,5) = "#DEFI" ;
  2883.                     OR LEFT(m.upline,3) = "#IF" ;
  2884.                     OR LEFT(m.upline,5) = "#ELSE" ;
  2885.                     OR LEFT(m.upline,6) = "#ENDIF" ;
  2886.                     OR LEFT(m.upline,8) = "#INCLUDE" 
  2887.                 \<<m.line>>
  2888.                 ENDIF
  2889.            CASE m.emptysubwind    && the most common case
  2890.             \<<m.line>>
  2891.          OTHERWISE
  2892.             m.at = atwname(m.subwindname, m.line)
  2893.             IF m.at <> 0 AND !iscomment(@upline)
  2894.                m.expr = STUFF(m.line, m.at, ;
  2895.                   LEN(m.subwindname), ;
  2896.                   g_screens[m.scrnno,2])
  2897.                \<<m.expr>>
  2898.             ELSE
  2899.                \<<m.line>>
  2900.             ENDIF
  2901.          ENDCASE
  2902.       ENDIF
  2903.    ENDFOR
  2904. ELSE   && not in setup
  2905.    FOR m.i = m.start TO m.linecnt
  2906.       m.line = MLINE(m.memo, 1, _MLINE)
  2907.       DO killcr WITH m.line
  2908.       m.upline = UPPER(LTRIM(CHRTRAN(m.line,chr(9),' ')))
  2909.       DO writeline WITH m.line, m.platname, m.platnum, m.upline, m.scrnno
  2910.    ENDFOR
  2911. ENDIF
  2912. SET EXACT &in_exact
  2913. RETURN
  2914.  
  2915. *!*****************************************************************************
  2916. *!
  2917. *!      Procedure: WRITELINE
  2918. *!
  2919. *!      Called by: EMITPROC           (procedure in GENSCRN.PRG)
  2920. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2921. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2922. *!
  2923. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2924. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2925. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2926. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2927. *!
  2928. *!*****************************************************************************
  2929. PROCEDURE writeline
  2930. *)
  2931. *) WRITELINE - Emit a single line
  2932. *)
  2933. PARAMETER m.line, m.platname, m.platnum, m.upline, m.scrnno
  2934. PRIVATE m.at, m.expr
  2935.  
  2936. IF !geninsertcode(@upline, m.scrnno, .F., m.platname)   && by reference to save time
  2937.    IF !EMPTY(g_wnames[m.scrnno, m.platnum])
  2938.       m.at = atwname(g_wnames[m.scrnno, m.platnum], m.line)
  2939.       IF m.at <> 0 AND !iscomment(@upline)
  2940.          m.expr = STUFF(m.line, m.at, ;
  2941.             LEN(g_wnames[m.scrnno, m.platnum]), ;
  2942.             g_screens[m.scrnno,2])
  2943.          \<<m.expr>>
  2944.       ELSE
  2945.          IF !INLIST(LEFT(m.upline,2),"*!","*:") ;
  2946.                AND AT('#NAME', m.upline) <> 1
  2947.             \<<m.line>>
  2948.          ENDIF
  2949.       ENDIF
  2950.    ELSE
  2951.        * This code relies upon partial matching (e.g., "*! Comment" will equal "*")
  2952.       DO CASE
  2953.         CASE m.upline = "*"
  2954.            IF !(m.upline = "*!" OR m.upline = "*:")
  2955.             \<<m.line>>
  2956.             ENDIF
  2957.         CASE m.upline = "#"
  2958.            * don't output a generator directive, but #DEFINES are OK
  2959.            IF LEFT(m.upline,5) = "#DEFI" ;
  2960.                     OR LEFT(m.upline,3) = "#IF" ;
  2961.                     OR LEFT(m.upline,5) = "#ELSE" ;
  2962.                     OR LEFT(m.upline,6) = "#ENDIF" ;
  2963.                     OR LEFT(m.upline,8) = "#INCLUDE" 
  2964.             \<<m.line>>
  2965.            ENDIF
  2966.         OTHERWISE
  2967.          \<<m.line>>
  2968.       ENDCASE
  2969.    ENDIF
  2970. ENDIF
  2971. RETURN
  2972.  
  2973. *!*****************************************************************************
  2974. *!
  2975. *!      Procedure: GENINSERTCODE
  2976. *!
  2977. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  2978. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2979. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  2980. *!
  2981. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2982. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  2983. *!
  2984. *!*****************************************************************************
  2985. PROCEDURE geninsertcode
  2986. *)
  2987. *) GENINSERTCODE - Emit code from the #insert file, if any
  2988. *)
  2989. *) Strg has to be trimmed before entering GenInsertCode.  It may be passed by reference.
  2990. PARAMETER m.strg, m.scrnno, m.insetup, m.platname
  2991. PRIVATE m.word1, m.filname
  2992. IF AT("#INSE",m.strg) = 1
  2993.    m.word1 = wordnum(m.strg,1)
  2994.    m.filname = SUBSTR(m.strg,LEN(m.word1)+1)
  2995.    m.filname = ALLTRIM(CHRTRAN(m.filname,CHR(9)," "))
  2996.    DO insertfile WITH m.filname, m.scrnno, m.insetup, m.platname
  2997.    RETURN .T.
  2998. ELSE
  2999.    RETURN .F.
  3000. ENDIF
  3001. RETURN
  3002.  
  3003. *!*****************************************************************************
  3004. *!
  3005. *!       Function: ISPARAMETER
  3006. *!
  3007. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3008. *!
  3009. *!          Calls: MATCH()            (function  in GENSCRN.PRG)
  3010. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  3011. *!
  3012. *!*****************************************************************************
  3013. FUNCTION isparameter
  3014. *)
  3015. *) ISPARAMETER - Determine if strg is a PARAMETERS statement
  3016. *)
  3017. PARAMETER m.strg
  3018. PRIVATE m.ispar
  3019. m.ispar = .F.
  3020. IF !EMPTY(strg) AND match(CHRTRAN(wordnum(strg,1),';',''),"PARAMETERS")
  3021.    m.ispar = .T.
  3022. ENDIF
  3023. RETURN m.ispar
  3024.  
  3025. *!*****************************************************************************
  3026. *!
  3027. *!       Function: ATWNAME
  3028. *!
  3029. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3030. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3031. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3032. *!
  3033. *!*****************************************************************************
  3034. FUNCTION atwname
  3035. *)
  3036. *) ATWNAME - Determine if valid m.string is in this line.
  3037. *)
  3038. *) Description:
  3039. *) Make sure that if m.string is in fact the string we want to do
  3040. *) the substitution on.
  3041. *)
  3042. PARAMETER m.string, m.line
  3043. PRIVATE m.pos, m.before, m.after
  3044. m.pos = AT(m.string,m.line)
  3045. IF m.pos = 0
  3046.    RETURN 0
  3047. ENDIF
  3048. IF m.pos = 1
  3049.    m.pos = AT(m.string+" ",m.line)
  3050. ELSE
  3051.    IF m.pos = LEN(m.line) - LEN(m.string) + 1
  3052.       m.pos = AT(" "+m.string,m.line)
  3053.       m.pos = IIF(m.pos<>0, m.pos+1,m.pos)
  3054.    ELSE
  3055.       m.before = SUBSTR(m.line,m.pos-1,1)
  3056.  
  3057.       IF m.before = c_under OR ;
  3058.             (m.before >= '0' AND m.before <= '9') OR ;
  3059.             (m.before >= 'a' AND m.before <= 'z') OR ;
  3060.             (m.before >= 'A' AND m.before <= 'Z')
  3061.  
  3062.          RETURN 0
  3063.       ENDIF
  3064.       m.after = SUBSTR(m.line,m.pos+LEN(m.string),1)
  3065.  
  3066.       IF m.after = c_under OR ;
  3067.             (m.after >= '0' AND m.after <= '9') OR ;
  3068.             (m.after >= 'a' AND m.after <= 'z') OR ;
  3069.             (m.after >= 'A' AND m.after <= 'Z')
  3070.  
  3071.          RETURN 0
  3072.       ENDIF
  3073.    ENDIF
  3074. ENDIF
  3075. RETURN m.pos
  3076.  
  3077. *!*****************************************************************************
  3078. *!
  3079. *!       Function: ISCOMMENT
  3080. *!
  3081. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3082. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3083. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3084. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  3085. *!
  3086. *!*****************************************************************************
  3087. FUNCTION iscomment
  3088. *)
  3089. *) ISCOMMENT - Determine if textline is a comment line.
  3090. *)
  3091. PARAMETER m.textline
  3092. PRIVATE m.asterisk, m.isnote, m.ampersand, m.statement
  3093. IF EMPTY(m.textline)
  3094.    RETURN .F.
  3095. ENDIF
  3096. m.statement = UPPER(LTRIM(m.textline))
  3097.  
  3098. m.asterisk  = AT("*", m.statement)
  3099. m.ampersand = AT(m.g_dblampersand, m.statement)
  3100. m.isnote    = AT("NOTE", m.statement)
  3101.  
  3102. DO CASE
  3103. CASE (m.asterisk = 1 OR m.ampersand = 1)
  3104.    RETURN .T.
  3105. CASE (m.isnote = 1 ;
  3106.       AND (LEN(m.statement) <= 4 OR SUBSTR(m.statement,5,1) = ' '))
  3107.    * Don't be fooled by something like "notebook = 7"
  3108.    RETURN .T.
  3109. ENDCASE
  3110. RETURN .F.
  3111.  
  3112. *!*****************************************************************************
  3113. *!
  3114. *!      Procedure: GENCLAUSECODE
  3115. *!
  3116. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  3117. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  3118. *!
  3119. *!          Calls: VALICLAUSE         (procedure in GENSCRN.PRG)
  3120. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  3121. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  3122. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  3123. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3124. *!
  3125. *!*****************************************************************************
  3126. PROCEDURE genclausecode
  3127. *)
  3128. *) GENCLAUSECODE - Generate code for all read-level clauses.
  3129. *)
  3130. *) Description:
  3131. *) Generate functions containing the code from each screen's
  3132. *) READ level valid, show, when, activate, and deactivate clauses.
  3133. *)
  3134. PARAMETER m.screenno
  3135. DO valiclause WITH m.screenno
  3136. DO whenclause WITH m.screenno
  3137. DO acticlause WITH m.screenno
  3138. DO deatclause WITH m.screenno
  3139. DO showclause WITH m.screenno
  3140. RETURN
  3141.  
  3142. *!*****************************************************************************
  3143. *!
  3144. *!      Procedure: VALICLAUSE
  3145. *!
  3146. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3147. *!
  3148. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3149. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  3150. *!
  3151. *!*****************************************************************************
  3152. PROCEDURE valiclause
  3153. *)
  3154. *) VALICLAUSE - Generate Read level Valid clause function.
  3155. *)
  3156. *) Description:
  3157. *) Generate the function containing the code segment(s) provided
  3158. *) by the user for the read level VALID clause.
  3159. *) If multiple reads have been chosen, then this procedure generates
  3160. *) a function for a single screen.
  3161. *) If single read has been chosen and there are multiple screens,
  3162. *) we will concatenate valid clause code segments form all screens
  3163. *) to form a single function.
  3164. *)
  3165. PARAMETER m.screenno
  3166. PRIVATE m.i, m.dbalias, m.thispretext
  3167.  
  3168. IF m.g_validtype = "EXPR" OR EMPTY(m.g_validtype)
  3169.    RETURN
  3170. ENDIF
  3171. DO genfuncheader WITH m.g_validname, "Read Level Valid", .T.
  3172. \FUNCTION <<m.g_validname>>     && Read Level Valid
  3173.  
  3174. m.thispretext = _PRETEXT
  3175. _PRETEXT = ""
  3176. IF m.g_multreads
  3177.    DO genvalidbody WITH m.screenno
  3178. ELSE
  3179.    FOR m.i = 1 TO m.g_nscreens
  3180.       m.g_screen = m.i
  3181.       m.dbalias = g_screens[m.i,5]
  3182.       SELECT (m.dbalias)
  3183.       DO genvalidbody WITH m.i
  3184.    ENDFOR
  3185.    m.g_screen = 0
  3186. ENDIF
  3187. _PRETEXT = m.thispretext
  3188. RETURN
  3189.  
  3190. *!*****************************************************************************
  3191. *!
  3192. *!      Procedure: GENVALIDBODY
  3193. *!
  3194. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  3195. *!
  3196. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3197. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3198. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3199. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3200. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3201. *!
  3202. *!*****************************************************************************
  3203. PROCEDURE genvalidbody
  3204. *)
  3205. *) GENVALIDBODY - Put out contents of a valid memo field.
  3206. *)
  3207. PARAMETER m.region
  3208. PRIVATE m.name, m.pos
  3209.  
  3210. IF g_screens[m.region, 6]
  3211.    LOCATE FOR objtype = c_otscreen
  3212. ELSE
  3213.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3214. ENDIF
  3215. IF NOT FOUND()
  3216.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3217.       LINENO(), c_error_3
  3218.    RETURN
  3219. ENDIF
  3220. IF NOT EMPTY(VALID) AND validtype<>0
  3221.    IF NOT m.g_multread
  3222.       m.name  = basename(DBF())
  3223.       DO gencomment WITH "Valid Code from screen: "+m.name
  3224.    ENDIF
  3225.    \#REGION <<INT(m.region)>>
  3226.    DO writecode WITH VALID, getplatname(m.region), c_fromone, c_untilend, m.region
  3227. ENDIF
  3228. RETURN
  3229.  
  3230. *!*****************************************************************************
  3231. *!
  3232. *!      Procedure: WHENCLAUSE
  3233. *!
  3234. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3235. *!
  3236. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3237. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  3238. *!
  3239. *!*****************************************************************************
  3240. PROCEDURE whenclause
  3241. *)
  3242. *) WHENCLAUSE - Generate Read level When clause function.
  3243. *)
  3244. *) Description:
  3245. *) Generate the function containing the code segment(s) provided
  3246. *) by the user for the read level WHEN clause.
  3247. *) If multiple reads have been chosen, then this procedure generates
  3248. *) a function for a single screen (i.e., the one it has been called for).
  3249. *) If single read has been chosen and there are multiple screens,
  3250. *) we will concatenate when clause code segments from all screens
  3251. *) to form a single function.
  3252. *)
  3253. PARAMETER m.screenno
  3254. PRIVATE m.i, m.dbalias, m.thispretext
  3255.  
  3256. IF m.g_whentype = "EXPR" OR EMPTY(m.g_whentype)
  3257.    RETURN
  3258. ENDIF
  3259. DO genfuncheader WITH m.g_whenname, "Read Level When", .T.
  3260. \FUNCTION <<m.g_whenname>>     && Read Level When
  3261.  
  3262. m.thispretext = _PRETEXT
  3263. _PRETEXT = ""
  3264. IF m.g_multreads
  3265.    DO genwhenbody WITH m.screenno
  3266. ELSE
  3267.    FOR m.i = 1 TO m.g_nscreens
  3268.       m.g_screen = m.i
  3269.       m.dbalias = g_screens[m.i,5]
  3270.       SELECT (m.dbalias)
  3271.       DO genwhenbody WITH m.i
  3272.    ENDFOR
  3273.    m.g_screen = 0
  3274. ENDIF
  3275. _PRETEXT = m.thispretext
  3276. RETURN
  3277.  
  3278. *!*****************************************************************************
  3279. *!
  3280. *!      Procedure: GENWHENBODY
  3281. *!
  3282. *!      Called by: WHENCLAUSE         (procedure in GENSCRN.PRG)
  3283. *!
  3284. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3285. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3286. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3287. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3288. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3289. *!
  3290. *!*****************************************************************************
  3291. PROCEDURE genwhenbody
  3292. *)
  3293. *) GENWHENBODY - Put out contents of when memo field.
  3294. *)
  3295. PARAMETER m.region
  3296. PRIVATE m.name, m.pos
  3297.  
  3298. IF g_screens[m.region, 6]
  3299.    LOCATE FOR objtype = c_otscreen
  3300. ELSE
  3301.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3302. ENDIF
  3303. IF NOT FOUND()
  3304.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3305.       LINENO(), c_error_3
  3306.    RETURN
  3307. ENDIF
  3308.  
  3309. IF NOT EMPTY(WHEN) AND whentype<>0
  3310.    IF NOT m.g_multread
  3311.       m.name = basename(DBF())
  3312.       DO gencomment WITH "When Code from screen: "+m.name
  3313.    ENDIF
  3314.    \#REGION <<INT(m.region)>>
  3315.    DO writecode WITH WHEN, getplatname(m.region), c_fromone, c_untilend, m.region
  3316. ENDIF
  3317. RETURN
  3318.  
  3319. *!*****************************************************************************
  3320. *!
  3321. *!      Procedure: ACTICLAUSE
  3322. *!
  3323. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3324. *!
  3325. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3326. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3327. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3328. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3329. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3330. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3331. *!
  3332. *!*****************************************************************************
  3333. PROCEDURE acticlause
  3334. *)
  3335. *) ACTICLAUSE - Generate Read level Activate clause function.
  3336. *)
  3337. *) Description:
  3338. *) Generate the function containing the code segment(s) provided
  3339. *) by the user for the read level ACTIVATE clause.
  3340. *) If multiple reads have been chosen, then this procedure generates
  3341. *) a function for a single screen (i.e., the one it has been called for).
  3342. *) If single read has been chosen and there are multiple screens,
  3343. *) we will concatenate activate clause code segments from all screens
  3344. *) to form a single function.  Each individual screen's code
  3345. *) segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3346. *) Desk top will be represented by a null character. The above
  3347. *) mentioned is performed by the procedure genactibody.
  3348. *)
  3349. PARAMETER m.screenno
  3350. PRIVATE m.i, m.name
  3351.  
  3352. IF m.g_actitype = "EXPR" OR EMPTY(m.g_actitype)
  3353.    RETURN
  3354. ENDIF
  3355. DO genfuncheader WITH m.g_actiname, "Read Level Activate", .T.
  3356. \FUNCTION <<m.g_actiname>>     && Read Level Activate
  3357.  
  3358. IF m.g_multreads
  3359.    IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3360.       \#REGION <<INT(m.screenno)>>
  3361.       DO writecode WITH ACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3362.    ENDIF
  3363. ELSE
  3364.    FOR m.i = 1 TO m.g_nscreens
  3365.       m.g_screen = m.i
  3366.       m.dbalias = g_screens[m.i,5]
  3367.       SELECT (m.dbalias)
  3368.       IF g_screens[m.i, 6]
  3369.          LOCATE FOR objtype = c_otscreen
  3370.       ELSE
  3371.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3372.       ENDIF
  3373.       IF NOT FOUND()
  3374.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3375.             LINENO(), c_error_3
  3376.          RETURN
  3377.       ENDIF
  3378.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3379.          m.name = basename(g_screens[m.i,1])
  3380.          DO gencomment WITH "Activate Code from screen: "+;
  3381.             m.name
  3382.       ENDIF
  3383.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3384.          \#REGION <<INT(m.i)>>
  3385.          DO writecode WITH ACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3386.       ENDIF
  3387.    ENDFOR
  3388.    m.g_screen = 0
  3389. ENDIF
  3390. RETURN
  3391.  
  3392. *!*****************************************************************************
  3393. *!
  3394. *!      Procedure: DEATCLAUSE
  3395. *!
  3396. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3397. *!
  3398. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3399. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3400. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3401. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3402. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3403. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3404. *!
  3405. *!*****************************************************************************
  3406. PROCEDURE deatclause
  3407. *)
  3408. *) DEATCLAUSE - Generate Read level deactivate clause function.
  3409. *)
  3410. *) Description:
  3411. *) Generate the function containing the code segment(s) provided
  3412. *) by the user for the read level DEACTIVATE clause.
  3413. *) If multiple reads have been chosen, then this procedure generates
  3414. *) a function for a single screen (i.e., the one it has been called for).
  3415. *) If single read has been chosen and there are multiple screens,
  3416. *) we will concatenate deactivate clause code segments from all screens
  3417. *) to form a single function.  Each individual screen's code
  3418. *) segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3419. *) Desk top will be represented by a null character. The above
  3420. *) mentioned is performed by the procedure gendeatbody.
  3421. *)
  3422. PARAMETER m.screenno
  3423. PRIVATE m.i, m.name
  3424.  
  3425. IF m.g_deattype = "EXPR" OR EMPTY(m.g_deattype)
  3426.    RETURN
  3427. ENDIF
  3428. DO genfuncheader WITH m.g_deatname, "Read Level Deactivate", .T.
  3429. \FUNCTION <<m.g_deatname>>     && Read Level Deactivate
  3430.  
  3431. IF m.g_multreads
  3432.    IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3433.       \#REGION <<INT(m.screenno)>>
  3434.       DO writecode WITH DEACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3435.    ENDIF
  3436. ELSE
  3437.    FOR m.i = 1 TO m.g_nscreens
  3438.       m.g_screen = m.i
  3439.       m.dbalias = g_screens[m.i,5]
  3440.       SELECT (m.dbalias)
  3441.       IF g_screens[m.i,6]
  3442.          LOCATE FOR objtype = c_otscreen
  3443.       ELSE
  3444.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3445.       ENDIF
  3446.       IF NOT FOUND()
  3447.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3448.             LINENO(), c_error_3
  3449.          RETURN
  3450.       ENDIF
  3451.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3452.          m.name = basename(g_screens[m.i,1])
  3453.          DO gencomment WITH "Deactivate Code from screen: "+;
  3454.             m.name
  3455.       ENDIF
  3456.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3457.          \#REGION <<INT(m.i)>>
  3458.          DO writecode WITH DEACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3459.       ENDIF
  3460.    ENDFOR
  3461.    m.g_screen = 0
  3462. ENDIF
  3463. RETURN
  3464.  
  3465. *!*****************************************************************************
  3466. *!
  3467. *!      Procedure: SHOWCLAUSE
  3468. *!
  3469. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3470. *!
  3471. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3472. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3473. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3474. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3475. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  3476. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3477. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3478. *!
  3479. *!*****************************************************************************
  3480. PROCEDURE showclause
  3481. *)
  3482. *) SHOWCLAUSE - Generate Read level Show clause procedure.
  3483. *)
  3484. *) Description:
  3485. *) Generate the function containing the code segment(s) provided
  3486. *) by the user for the read level SHOW clause.  The function generated
  3487. *) for the show clause will consist of refreshable @...SAY code and
  3488. *) code segment(s) if applicable. If multiple reads have been chosen,
  3489. *) then this procedure generates a function for a single screen
  3490. *) (i.e., the one it has been called for).  If single read has been
  3491. *) chosen and there are multiple screens, we will concatenate show
  3492. *) clause code segments from all screens to form a single function.
  3493. *) Each individual screen's refreshable SAYs will be enclosed in
  3494. *) "IF SYS(2016)=('windowname') OR SYS(2016) = '*'" statement.
  3495. *) (Desk top will be represented by a null character.)
  3496. *)
  3497. PARAMETER m.screenno
  3498. PRIVATE m.i, m.comment, m.name, m.thispretext, m.oldshow, m.showmod
  3499.  
  3500. IF m.g_showtype = "EXPR" OR EMPTY(m.g_showtype)
  3501.    RETURN
  3502. ENDIF
  3503. DO genfuncheader WITH m.g_showname, "Read Level Show", .T.
  3504.  
  3505. \FUNCTION <<m.g_showname>>     && Read Level Show
  3506. \PRIVATE currwind
  3507.  
  3508. \STORE WOUTPUT() TO currwind
  3509. m.thispretext = _PRETEXT
  3510. _PRETEXT = ""
  3511.  
  3512. IF m.g_multreads
  3513.    DO seekheader WITH m.screenno
  3514.    m.oldshow = Show
  3515.  
  3516.    m.showmod = ChkShow()
  3517.  
  3518.    m.comment = .T.
  3519.    \#REGION <<INT(m.screenno)>>
  3520.    IF NOT EMPTY(show) AND showtype<>0
  3521.       DO writecode WITH show, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3522.    ENDIF
  3523.    DO placesays WITH m.comment, m.g_showname, m.screenno
  3524.    IF m.showmod
  3525.       REPLACE show WITH m.oldshow
  3526.    ENDIF
  3527. ELSE
  3528.    FOR m.i = 1 TO m.g_nscreens
  3529.       m.g_screen = m.i
  3530.       m.dbalias = g_screens[m.i,5]
  3531.       SELECT (m.dbalias)
  3532.       m.comment = .F.
  3533.  
  3534.       DO seekheader WITH m.i
  3535.  
  3536.       m.name = basename(g_screens[m.i,1])
  3537.       IF NOT EMPTY(show) AND showtype<>0
  3538.          m.oldshow = Show   && record show snippet
  3539.          m.showmod = ChkShow()         && may modify show snippet directly
  3540.  
  3541.          DO gencomment WITH "Show Code from screen: "+m.name
  3542.          \#REGION <<INT(m.i)>>
  3543.          m.comment = .T.
  3544.          DO writecode WITH show, getplatname(m.i), c_fromone, c_untilend, m.i
  3545.          IF m.showmod
  3546.             REPLACE show WITH m.oldshow
  3547.          ENDIF
  3548.       ENDIF
  3549.       DO seekheader WITH m.i
  3550.       DO placesays WITH m.comment, m.name, m.i
  3551.    ENDFOR
  3552.    m.g_screen = 0
  3553. ENDIF
  3554. _PRETEXT = m.thispretext
  3555.  
  3556. IF !m.g_noreadplain
  3557.    \IF NOT EMPTY(currwind)
  3558.    \    ACTIVATE WINDOW (currwind) SAME
  3559.    \ENDIF
  3560. ENDIF
  3561. RETURN
  3562.  
  3563. *!*****************************************************************************
  3564. *!
  3565. *!      Function: CHKSHOW
  3566. *!
  3567. *!*****************************************************************************
  3568. FUNCTION chkshow
  3569. PRIVATE m.thelineno, m.theline, m.oldmline, m.upline, m.newshow, m.found_one, m.leadspace, ;
  3570.    m.oldtext, m.theword, m.getsonly, m.j
  3571. * Check for a poisonous SHOW GETS in the SHOW snippet.  If one if executed
  3572. * there, runaway recursion results.
  3573. IF c_checkshow == 0   && check to see if this safety feature is enabled.
  3574.    RETURN .F.
  3575. ENDIF
  3576. m.thelineno = ATCLINE("SHOW GETS",show)
  3577. m.oldmline = _MLINE
  3578. m.oldtext = _TEXT
  3579. m.found_one = .F.
  3580. IF m.thelineno > 0
  3581.    * Step through the SHOW snippet a line at a time, commenting out any SHOW GETS or
  3582.    * SHOW GETS OFF statements.
  3583.    m.newshow = ""
  3584.    _MLINE = 0
  3585.    DO WHILE _MLINE < LEN(show)
  3586.       m.theline = MLINE(show,1,_MLINE)
  3587.       DO killcr WITH m.theline
  3588.       m.upline  = UPPER(LTRIM(m.theline))
  3589.       IF wordnum(m.upline,1) == "SHOW" AND wordnum(m.upline,2) == "GETS" ;
  3590.              AND (EMPTY(wordnum(m.upline,3)) OR wordnum(m.upline,3) == "OFF")
  3591.          m.leadspace = LEN(m.theline) - LEN(m.upline)
  3592.          m.newshow = m.newshow + SPACE(m.leadspace) + ;
  3593.             "* Commented out by GENSCRN: " + LTRIM(m.theline) + CHR(13) + CHR(10)
  3594.          DO errorhandler WITH "SHOW GETS statement commented out of SHOW snippet.",;
  3595.               LINENO(),c_error_1
  3596.          m.found_one = .T.
  3597.       ELSE
  3598.          m.newshow = m.newshow + m.theline + CHR(13) + CHR(10)
  3599.       ENDIF
  3600.    ENDDO
  3601.    IF m.found_one
  3602.       REPLACE show WITH m.newshow
  3603.    ENDIF
  3604. ENDIF
  3605. _MLINE = m.oldmline
  3606. _TEXT  = m.oldtext
  3607. RETURN m.found_one
  3608.  
  3609. *!*****************************************************************************
  3610. *!
  3611. *!      Procedure: PLACESAYS
  3612. *!
  3613. *!      Called by: SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3614. *!
  3615. *!          Calls: GENCOMMENT         (procedure in GENSCRN.PRG)
  3616. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3617. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  3618. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  3619. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  3620. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  3621. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  3622. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  3623. *!
  3624. *!*****************************************************************************
  3625. PROCEDURE placesays
  3626. *)
  3627. *) PLACESAYS - Generate @...SAY for refreshable says in the .PRG file.
  3628. *)
  3629. *) Description:
  3630. *) Place @...SAY code for all refreshable say statements into
  3631. *) the generated SHOW clause function.
  3632. *)
  3633. PARAMETER m.comment, m.scrnname, m.g_thisscreen
  3634. PRIVATE m.iswindow, m.sayfound, m.windowname, m.theexpr, m.occur, m.pos
  3635.  
  3636. IF EMPTY(STYLE)
  3637.    m.iswindow = .F.
  3638. ELSE
  3639.    m.iswindow = .T.
  3640.    m.windowname = g_screens[m.g_thisscreen,2]
  3641. ENDIF
  3642. m.sayfound = .T.
  3643. SCAN FOR ((objtype = c_otfield AND objcode = c_sgsay) OR ;
  3644.       (objtype = c_otpicture)) AND ;
  3645.       REFRESH = .T. AND (g_screens[m.g_thisscreen, 6] OR platform = g_screens[m.g_thisscreen, 7])
  3646.    IF m.sayfound
  3647.       IF NOT m.comment
  3648.          DO gencomment WITH "Show Code from screen: "+m.scrnname
  3649.          \#REGION <<INT(m.g_thisscreen)>>
  3650.       ENDIF
  3651.       IF !m.g_noreadplain    && not just emitting plain @ SAYs/GETs
  3652.          \IF SYS(2016) =
  3653.          IF m.iswindow
  3654.             \\ "<<UPPER(m.windowname)>>" OR SYS(2016) = "*"
  3655.             \    ACTIVATE WINDOW <<m.windowname>> SAME
  3656.          ELSE
  3657.             \\ "" OR SYS(2016) = "*"
  3658.             \    ACTIVATE SCREEN
  3659.          ENDIF
  3660.       ENDIF
  3661.       m.sayfound = .F.
  3662.    ENDIF
  3663.  
  3664.    IF objtype = c_otpicture
  3665.       DO genpicture
  3666.    ELSE
  3667.       m.theexpr = expr
  3668.       IF g_screens[m.g_thisscreen, 7] = 'WINDOWS' OR g_screens[m.g_thisscreen, 7] = 'MAC'
  3669.          SET DECIMALS TO 3
  3670.          m.occur = 1
  3671.          m.pos = AT(CHR(13), m.theexpr, m.occur)
  3672.  
  3673.          * Sometimes the screen builder surrounds text with single quotes and other
  3674.          * times with double quotes.
  3675.          q1 = LEFT(LTRIM(m.theexpr),1)
  3676.  
  3677.          DO WHILE m.pos > 0
  3678.             IF q1 = "'"
  3679.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3680.                   "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  3681.                   + SUBSTR(m.theexpr, m.pos + 1)
  3682.             ELSE
  3683.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3684.                   '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  3685.                   + SUBSTR(m.theexpr, m.pos + 1)
  3686.             ENDIF
  3687.             m.occur = m.occur + 1
  3688.             m.pos = AT(CHR(13), m.theexpr, m.occur)
  3689.          ENDDO
  3690.          IF mode = 1 AND objtype = c_otfield  AND objcode = c_sgsay    && transparent SAY text
  3691.             * Clear the space that the SAY is going into.  This makes refreshable SAYS
  3692.             * work with transparent fonts.
  3693.             \    @ <<Vpos>>,<<Hpos>> CLEAR TO <<Vpos+Height>>,<<Hpos+Width>>
  3694.          ENDIF
  3695.       ENDIF
  3696.       \    @ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  3697.       \        SIZE <<Height>>,<<Width>>, <<Spacing>>
  3698.       SET DECIMALS TO 0
  3699.       DO pushindent
  3700.       DO anyfont
  3701.       DO anystyle
  3702.       DO anypicture
  3703.       DO anyscheme
  3704.       DO popindent
  3705.    ENDIF
  3706. ENDSCAN
  3707. IF NOT m.sayfound
  3708.    \ENDIF
  3709. ENDIF
  3710. RETURN
  3711.  
  3712. *!*****************************************************************************
  3713. *!
  3714. *!      Procedure: GENCLOSEDBFS
  3715. *!
  3716. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  3717. *!
  3718. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3719. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3720. *!
  3721. *!*****************************************************************************
  3722. PROCEDURE genclosedbfs
  3723. *)
  3724. *) GENCLOSEDBFS - Generate code to close all previously opened databases.
  3725. *)
  3726. PRIVATE m.i, m.dbalias, m.dbfcnt, m.firstfound
  3727. m.firstfound = .T.
  3728. m.dbfcnt = 0
  3729. g_dbfs = ""
  3730. FOR m.i = 1 TO m.g_nscreens
  3731.    m.g_screen = m.i
  3732.    m.dbalias = g_screens[m.i,5]
  3733.    SELECT (m.dbalias)
  3734.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3735.       IF m.firstfound
  3736.          DO commentblock WITH ""," Closing Databases"
  3737.          m.firstfound = .F.
  3738.       ENDIF
  3739.       IF uniquedbf(TAG)
  3740.          m.dbfcnt = m.dbfcnt + 1
  3741.          DIMENSION g_dbfs[m.dbfcnt]
  3742.          g_dbfs[m.dbfcnt] = TAG
  3743.       ELSE
  3744.          LOOP
  3745.       ENDIF
  3746.       \IF USED("<<LOWER(stripext(strippath(Tag)))>>")
  3747.       \    SELECT <<LOWER(stripext(strippath(Tag)))>>
  3748.       \    USE
  3749.       \ENDIF
  3750.       \
  3751.    ENDSCAN
  3752. ENDFOR
  3753. m.g_screen = 0
  3754. IF m.g_closefiles 
  3755.    \SELECT (m.currarea)
  3756.    \
  3757. ENDIF
  3758. DIMENSION g_dbfs[1]
  3759. RETURN
  3760.  
  3761. *!*****************************************************************************
  3762. *!
  3763. *!      Procedure: GENOPENDBFS
  3764. *!
  3765. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  3766. *!
  3767. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3768. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3769. *!               : GENUSESTMTS        (procedure in GENSCRN.PRG)
  3770. *!               : STRIPPATH()        (function  in GENSCRN.PRG)
  3771. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3772. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  3773. *!
  3774. *!*****************************************************************************
  3775. PROCEDURE genopendbfs
  3776. *)
  3777. *) GENOPENDBFS - Generate USE... statement(s).
  3778. *)
  3779. *) Description:
  3780. *) Generate code to open databases, set indexes, and relations as
  3781. *) specified by the user.
  3782. *)
  3783. PRIVATE m.dbalias, m.i, m.dbfcnt, m.string, m.msg, m.firstfound
  3784. m.firstfound = .T.
  3785. FOR m.i = 1 TO m.g_nscreens
  3786.    m.g_screen = m.i
  3787.    m.dbalias = g_screens[m.i,5]
  3788.    SELECT (m.dbalias)
  3789.    m.dbfcnt = 0
  3790.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3791.       IF m.firstfound
  3792.          DO commentblock WITH m.dbalias, ;
  3793.             " Databases, Indexes, Relations"
  3794.          m.firstfound = .F.
  3795.       ENDIF
  3796.       IF uniquedbf(TAG)
  3797.          m.dbfcnt = m.dbfcnt + 1
  3798.          DIMENSION g_dbfs[m.dbfcnt]
  3799.          g_dbfs[m.dbfcnt] = TAG
  3800.       ELSE
  3801.          LOOP
  3802.       ENDIF
  3803.       DO genusestmts WITH m.i
  3804.    ENDSCAN
  3805.  
  3806.    IF m.dbfcnt > 1
  3807.       IF NOT EMPTY(m.g_current)
  3808.          \SELECT <<m.g_current>>
  3809.       ELSE
  3810.          m.msg = "Please RE-SAVE screen environment... SCREEN: "+;
  3811.             strippath(g_screens[m.i,1])
  3812.          DO errorhandler WITH m.msg, LINENO(), c_error_1
  3813.       ENDIF
  3814.       \
  3815.    ENDIF
  3816. ENDFOR
  3817. m.g_screen = 0
  3818. DO genrelations
  3819. RETURN
  3820.  
  3821. *!*****************************************************************************
  3822. *!
  3823. *!       Function: UNIQUEDBF
  3824. *!
  3825. *!      Called by: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  3826. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  3827. *!
  3828. *!*****************************************************************************
  3829. FUNCTION uniquedbf
  3830. *)
  3831. *) UNIQUEDBF - Check if database name already seen.
  3832. *)
  3833. PARAMETER m.dbfname
  3834. RETURN IIF(ASCAN(g_dbfs, m.dbfname)=0,.T.,.F.)
  3835.  
  3836. *!*****************************************************************************
  3837. *!
  3838. *!      Procedure: GENUSESTMTS
  3839. *!
  3840. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  3841. *!
  3842. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  3843. *!               : GENORDER           (procedure in GENSCRN.PRG)
  3844. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3845. *!
  3846. *!*****************************************************************************
  3847. PROCEDURE genusestmts
  3848. *)
  3849. *) GENUSESTMTS - Generate USE... statements
  3850. *)
  3851. *) Description:
  3852. *) Generate USE... statements for each database encoded in the
  3853. *) screen database.  Generate ORDER statement if appropriate.
  3854. *)
  3855. PARAMETER m.i
  3856. PRIVATE m.workarea, saverecno, MARGIN, m.name, m.order, m.tag
  3857. m.workarea  = objcode
  3858. saverecno = RECNO()
  3859. m.order   = LOWER(ALLTRIM(ORDER))
  3860. m.tag     = LOWER(ALLTRIM(tag2))
  3861. m.name    = LOWER(TAG)
  3862. m.relpath = LOWER(findrelpath(name))
  3863.  
  3864. IF UNIQUE AND EMPTY(m.g_current)
  3865.    m.g_current = m.name
  3866. ENDIF
  3867.  
  3868. MARGIN = 4
  3869. IF EMPTY(name)
  3870.    \SELECT <<m.name>>
  3871.    RETURN
  3872. ENDIF
  3873. \IF USED("<<m.name>>")
  3874. \    SELECT <<m.name>>
  3875. IF genindexes ("select", m.i)=0
  3876.    indexfound = 0
  3877.    \    SET ORDER TO
  3878.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3879. ELSE
  3880.    indexfound = 1
  3881.    \\ ADDITIVE ;
  3882.    \        ORDER
  3883.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3884. ENDIF
  3885.  
  3886. \ELSE
  3887. \    SELECT 0
  3888. \    USE (LOCFILE("<<m.relpath>>","DBF",
  3889. \\"Where is <<basename(m.relpath)>>?"));
  3890. \        AGAIN ALIAS <<m.name>>
  3891. MARGIN = 42+LEN(m.relpath)+2*LEN(m.name)
  3892. = genindexes("use", m.i)
  3893.  
  3894. GOTO saverecno
  3895. \\ ;
  3896. \        ORDER
  3897. DO genorder WITH indexfound,m.order,m.tag,m.name
  3898. \ENDIF
  3899. \
  3900. RETURN
  3901.  
  3902. *!*****************************************************************************
  3903. *!
  3904. *!       Function: FINDRELPATH
  3905. *!
  3906. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3907. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3908. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3909. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  3910. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  3911. *!               : ANYICON            (procedure in GENSCRN.PRG)
  3912. *!
  3913. *!*****************************************************************************
  3914. FUNCTION findrelpath
  3915. *)
  3916. *) FINDRELPATH - Find relative path for DATABASES.
  3917. *)
  3918. PARAMETER m.name
  3919. PRIVATE m.fullpath, m.relpath
  3920. m.fullpath = UPPER(FULLPATH(m.name, g_screens[1,1]))
  3921. m.relpath  = SYS(2014, m.fullpath, UPPER(m.g_homedir))
  3922. RETURN m.relpath
  3923.  
  3924. *!*****************************************************************************
  3925. *!
  3926. *!      Procedure: GENORDER
  3927. *!
  3928. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3929. *!
  3930. *!*****************************************************************************
  3931. PROCEDURE genorder
  3932. *)
  3933. *) GENORDER - Generate ORDER clause.
  3934. *)
  3935. PARAMETER m.indexfound, m.order, m.tag, m.dbfname
  3936. IF EMPTY(m.order) AND EMPTY(m.tag)
  3937.    \\ 0
  3938.    RETURN
  3939. ENDIF
  3940. IF m.indexfound=0
  3941.    \\ TAG "<<m.tag>>"
  3942. ELSE
  3943.    IF EMPTY(m.tag)
  3944.       \\ <<basename(m.order)>>
  3945.    ELSE
  3946.       \\ TAG "<<m.tag>>"
  3947.       IF NOT EMPTY (m.order)
  3948.          \\ OF <<m.order>>
  3949.       ENDIF
  3950.    ENDIF
  3951. ENDIF
  3952. RETURN
  3953.  
  3954. *!*****************************************************************************
  3955. *!
  3956. *!       Function: GENINDEXES
  3957. *!
  3958. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3959. *!
  3960. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  3961. *!
  3962. *!*****************************************************************************
  3963. FUNCTION genindexes
  3964. *)
  3965. *) GENINDEXES - Generate index names for a USE statement.
  3966. *)
  3967. PARAMETER m.placement, m.i
  3968. PRIVATE m.idxcount, m.relpath
  3969. m.idxcount = 0
  3970.  
  3971. SCAN FOR objtype = c_otindex AND objcode = WORKAREA AND;
  3972.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3973.    m.relpath = LOWER(findrelpath(name))
  3974.    IF m.idxcount > 0
  3975.       IF MARGIN > 55
  3976.          MARGIN = 8 + LEN(m.relpath)
  3977.          \\, ;
  3978.          \        <<m.relpath>>
  3979.       ELSE
  3980.          \\, <<m.relpath>>
  3981.          MARGIN = MARGIN + 2 + LEN(m.relpath)
  3982.       ENDIF
  3983.    ELSE
  3984.       IF m.placement = "use"
  3985.          \\ ;
  3986.          \        INDEX <<m.relpath>>
  3987.          MARGIN = 8 + LEN(m.relpath)
  3988.       ELSE
  3989.          \    SET INDEX TO <<m.relpath>>
  3990.          MARGIN = 17
  3991.          MARGIN = MARGIN + LEN(m.relpath)
  3992.       ENDIF
  3993.    ENDIF
  3994.    m.idxcount = m.idxcount + 1
  3995. ENDSCAN
  3996. RETURN m.idxcount
  3997.  
  3998. *!*****************************************************************************
  3999. *!
  4000. *!      Procedure: GENRELATIONS
  4001. *!
  4002. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  4003. *!
  4004. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4005. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  4006. *!
  4007. *!*****************************************************************************
  4008. PROCEDURE genrelations
  4009. *)
  4010. *) GENRELATIONS - Generate code to set all existing relations as they
  4011. *)                 are encoded in the screen file(s).
  4012. *)
  4013. *) Description:
  4014. *) Generate code for all relations as encoded in the screen database.
  4015. *)
  4016. PRIVATE m.dbalias, m.i
  4017. FOR m.i = 1 TO m.g_nscreens
  4018.    m.g_screen = m.i
  4019.    m.dbalias  = g_screens[m.i,5]
  4020.    SELECT (m.dbalias)
  4021.  
  4022.    DO seekheader WITH m.i
  4023.    DO genrelstmts WITH m.i
  4024. ENDFOR
  4025. m.g_screen = 0
  4026. RETURN
  4027.  
  4028. *!*****************************************************************************
  4029. *!
  4030. *!      Procedure: GENRELSTMTS
  4031. *!
  4032. *!      Called by: GENRELATIONS       (procedure in GENSCRN.PRG)
  4033. *!
  4034. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  4035. *!
  4036. *!*****************************************************************************
  4037. PROCEDURE genrelstmts
  4038. *)
  4039. *) GENRELSTMTS - Generate relation statements.
  4040. *)
  4041. PARAMETER m.i
  4042. PRIVATE m.saverec, m.last, m.firstrel, m.firstsel, m.dbalias, m.setskip
  4043. m.dbalias  = ""
  4044. m.firstrel = .T.
  4045. m.firstsel = .T.
  4046. m.last     = 0
  4047. m.setskip  = ""
  4048.  
  4049. SCAN FOR objtype = c_otrel AND ;
  4050.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4051.    IF m.last<> objcode
  4052.       IF NOT (m.firstrel OR EMPTY(m.setskip))
  4053.          \SET SKIP TO <<m.setskip>>
  4054.          \
  4055.       ENDIF
  4056.       m.saverec = RECNO()
  4057.       m.last= objcode
  4058.  
  4059.       SCAN FOR objtype = c_otworkarea AND objcode = m.last AND ;
  4060.             (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4061.          m.dbalias = LOWER(basename(TAG))
  4062.          IF NOT (m.firstrel AND m.g_current = m.dbalias)
  4063.             \SELECT <<m.dbalias>>
  4064.          ENDIF
  4065.          m.setskip = ALLTRIM(LOWER(expr))
  4066.       ENDSCAN
  4067.  
  4068.       GOTO RECORD m.saverec
  4069.       m.firstrel = .F.
  4070.    ENDIF
  4071.  
  4072.    IF !(m.firstsel AND LOWER(tag2) == LOWER(m.g_current))
  4073.       \SELECT <<LOWER(Tag2)>>
  4074.       \
  4075.    ENDIF
  4076.    \SET RELATION OFF INTO <<LOWER(Tag)>>
  4077.    \SET RELATION TO <<LOWER(Expr)>> INTO <<LOWER(Tag)>> ADDITIVE
  4078.    \
  4079.  
  4080.    m.firstsel = .F.
  4081. ENDSCAN
  4082.  
  4083. IF m.last<> 0
  4084.    IF NOT EMPTY(m.setskip)
  4085.       \SET SKIP TO <<m.setskip>>
  4086.       \
  4087.    ENDIF
  4088.    IF NOT EMPTY(m.g_current)
  4089.       \SELECT <<m.g_current>>
  4090.    ENDIF
  4091. ENDIF
  4092. RETURN
  4093.  
  4094. **
  4095. ** Code Associated With Building of the Format file statements.
  4096. **
  4097.  
  4098. *!*****************************************************************************
  4099. *!
  4100. *!      Procedure: BUILDFMT
  4101. *!
  4102. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4103. *!
  4104. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  4105. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  4106. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  4107. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  4108. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4109. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4110. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  4111. *!               : ANYWINDOWS         (procedure in GENSCRN.PRG)
  4112. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  4113. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  4114. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  4115. *!               : GENLINES           (procedure in GENSCRN.PRG)
  4116. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  4117. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  4118. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  4119. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  4120. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  4121. *!               : GENLIST            (procedure in GENSCRN.PRG)
  4122. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  4123. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  4124. *!               : GENACTISTMTS       (procedure in GENSCRN.PRG)
  4125. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  4126. *!
  4127. *!*****************************************************************************
  4128. PROCEDURE buildfmt
  4129. *)
  4130. *) BUILDFMT - Build Format file statements.
  4131. *)
  4132. *) Description:
  4133. *) Generate all boxes, text, fields, push buttons, radio buttons,
  4134. *) popups, check boxes and scrollable lists encoded in a screen set.
  4135. *)
  4136. PARAMETER pnum   && platform number
  4137. PRIVATE m.pos, m.dbalias, m.adjuster, m.recadjust, m.increment, m.i, m.sn
  4138. m.msg = 'Generating Screen Code'
  4139. IF multiplat()
  4140.    m.msg = m.msg + " for "+versioncap(m.g_genvers, m.g_dualoutput)
  4141. ENDIF
  4142. DO putmsg WITH m.msg
  4143. m.g_nwindows = 0
  4144. m.adjuster   = INT((c_therm4-c_therm3)/m.g_nscreens)  && total therm. range to cover
  4145. m.recadjust  = c_therm3                 && starting position for thermometer
  4146. FOR m.sn = 1 TO m.g_nscreens
  4147.    m.g_screen = m.sn
  4148.    m.dbalias = g_screens[m.sn,5]
  4149.    SELECT (m.dbalias)
  4150.    DO seekheader WITH m.sn
  4151.  
  4152.    DO commentblock WITH g_screens[m.sn,1], " Screen Layout"
  4153.    \#REGION <<INT(m.sn)>>
  4154.    IF ATC('#ITSE',setupcode)<>0
  4155.       DO gendirective WITH ;
  4156.          MLINE(setupcode,ATCLINE('#ITSE',setupcode)),;
  4157.          '#ITSE'
  4158.    ENDIF
  4159.  
  4160.    * Figure out thermometer increment
  4161.    IF g_screens[m.sn, 6] OR m.g_numplatforms = 1
  4162.       m.recs = RECCOUNT()
  4163.    ELSE 
  4164.       GOTO TOP
  4165.       COUNT FOR platform = g_screens[m.sn, 7] TO m.recs
  4166.    ENDIF 
  4167.    m.increment = m.adjuster/m.recs
  4168.  
  4169.    SCAN FOR (g_screens[m.sn, 6] OR platform = g_screens[m.sn, 7])
  4170.       m.recadjust = m.recadjust + m.increment
  4171.  
  4172.       DO updtherm WITH thermadj(m.pnum,INT(m.recadjust),c_therm5)
  4173.  
  4174.       DO CASE
  4175.       CASE objtype = c_otscreen
  4176.          DO anywindows WITH (m.sn)
  4177.       CASE objtype = c_ottext
  4178.          DO gentext
  4179.       CASE objtype = c_otfield
  4180.          DO genfields
  4181.       CASE objtype = c_otbox
  4182.          DO genboxes
  4183.       CASE objtype = c_otline
  4184.          DO genlines
  4185.       CASE objtype = c_ottxtbut
  4186.          DO genpush
  4187.       CASE objtype = c_otradbut
  4188.          DO genradbut
  4189.       CASE objtype = c_otinvbut
  4190.          DO geninvbut
  4191.       CASE objtype = c_otpopup
  4192.          DO genpopup
  4193.       CASE objtype = c_otchkbox
  4194.          DO genchkbox
  4195.       CASE objtype = c_otlist
  4196.          DO genlist
  4197.       CASE objtype = c_otpicture
  4198.          DO genpicture
  4199.       CASE objtype = c_otspinner
  4200.          DO genspinner
  4201.       ENDCASE
  4202.    ENDSCAN
  4203.    DO genactistmts WITH (m.sn)
  4204.    IF !m.g_noread
  4205.       DO placeread WITH (m.sn)
  4206.    ENDIF
  4207. ENDFOR
  4208. m.g_screen = 0
  4209. RETURN
  4210.  
  4211. *!*****************************************************************************
  4212. *!
  4213. *!      Procedure: ANYWINDOWS
  4214. *!
  4215. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4216. *!
  4217. *!          Calls: GENACTWINDOW       (procedure in GENSCRN.PRG)
  4218. *!
  4219. *!*****************************************************************************
  4220. PROCEDURE anywindows
  4221. *)
  4222. *) ANYWINDOWS - Issue ACTIVATE WINDOW ... SAME.
  4223. *)
  4224. *) Description:
  4225. *) If windows present issue ACTIVATE WINDOW...SAME to make sure
  4226. *) that the windows stack on screen in the correct order.
  4227. *)
  4228. PARAMETER m.scrnno
  4229. PRIVATE m.pos
  4230. IF m.g_noreadplain
  4231.    RETURN
  4232. ENDIF
  4233.    
  4234. IF NOT EMPTY(STYLE)
  4235.    DO genactwindow WITH m.scrnno
  4236.  
  4237.    m.g_lastwindow = g_screens[m.scrnno,2]
  4238.    m.pos = ASCAN(g_wndows, m.g_lastwindow)
  4239.    * m.pos contains the element number (not the row) that matches.
  4240.    * The element number + 1 is a number representing window sequence.
  4241.    IF EMPTY(g_wndows[m.pos+1])
  4242.       m.g_nwindows = m.g_nwindows + 1
  4243.       g_wndows[m.pos+1] = m.g_nwindows
  4244.    ENDIF
  4245.  
  4246.    m.g_defasch1 = SCHEME
  4247.    m.g_defasch2 = scheme2
  4248. ELSE
  4249.    m.g_defasch1 = 0
  4250.    m.g_defasch2 = 0
  4251.  
  4252.    IF m.g_lastwindow<>""
  4253.       \HIDE WINDOW ALL
  4254.       \ACTIVATE SCREEN
  4255.       m.g_lastwindow = ""
  4256.    ENDIF
  4257. ENDIF
  4258. RETURN
  4259.  
  4260. *!*****************************************************************************
  4261. *!
  4262. *!      Procedure: GENACTISTMTS
  4263. *!
  4264. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4265. *!
  4266. *!*****************************************************************************
  4267. PROCEDURE genactistmts
  4268. *)
  4269. *) GENACTISTMTS - Generate Activate window statements.
  4270. *)
  4271. *) Description:
  4272. *) Generate ACTIVATE WINDOW... statements in order to activate all
  4273. *) windows which have been previously activated with SAME clause.
  4274. *)
  4275. PARAMETER m.scrnno
  4276. PRIVATE m.j, m.pos
  4277. \
  4278. IF m.scrnno=m.g_nscreens AND NOT m.g_multreads AND NOT m.g_noreadplain
  4279.    IF m.g_nwindows = 1
  4280.       \IF NOT WVISIBLE("<<g_wndows[1,1]>>")
  4281.       \    ACTIVATE WINDOW <<g_wndows[1,1]>>
  4282.       \ENDIF
  4283.       RETURN
  4284.    ENDIF
  4285.    FOR m.j = m.g_nwindows TO 1 STEP -1
  4286.       m.pos = ASCAN(g_wndows, m.j)
  4287.       * pos contains the element *numbered* j.  This will be somewhere in g_wndows[*,2].
  4288.       * Look to the preceding element to get the window name.
  4289.       IF m.pos<>0
  4290.          \IF NOT WVISIBLE("<<g_wndows[m.pos-1]>>")
  4291.          \    ACTIVATE WINDOW <<g_wndows[m.pos-1]>>
  4292.          \ENDIF
  4293.       ENDIF
  4294.    ENDFOR
  4295.    \
  4296. ENDIF
  4297. RETURN
  4298.  
  4299. *!*****************************************************************************
  4300. *!
  4301. *!      Procedure: PLACEREAD
  4302. *!
  4303. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4304. *!
  4305. *!          Calls: ANYMODAL           (procedure in GENSCRN.PRG)
  4306. *!               : ANYLOCK            (procedure in GENSCRN.PRG)
  4307. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4308. *!               : GENWITHCLAUSE      (procedure in GENSCRN.PRG)
  4309. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4310. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4311. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4312. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4313. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4314. *!
  4315. *!*****************************************************************************
  4316. PROCEDURE placeread
  4317. *)
  4318. *) PLACEREAD - Generate a 'READ' statement.
  4319. *)
  4320. *) Description:
  4321. *) Called once per screen in the screen set.
  4322. *) Generate a READ statement.  Depending on whether this is a single
  4323. *) or multiread the read statement may be generated between @...SAY/GETs
  4324. *) from each screen or at the end of a set of all @...SAY/GETs.
  4325. *)
  4326. PARAMETER m.scrnno
  4327. PRIVATE thispretext
  4328.  
  4329. \
  4330. IF m.g_multreads
  4331.    DO newreadclauses
  4332.    \READ
  4333.    IF m.g_readcycle AND m.scrnno = m.g_nscreens
  4334.       \\ CYCLE
  4335.    ENDIF
  4336.    DO anymodal
  4337.    DO anylock
  4338.    DO doplaceclause WITH m.scrnno
  4339.    DO genwithclause
  4340.    DO gengivenread WITH m.scrnno
  4341. ELSE
  4342.    IF NOT EMPTY(m.g_rddir) AND m.scrnno = m.g_nscreens
  4343.       DO commentblock WITH "","READ contains clauses from SCREEN "+;
  4344.          LOWER(g_screens[m.g_rddirno,5])
  4345.    ENDIF
  4346.    DO findreadclauses WITH m.scrnno
  4347.    IF m.scrnno = m.g_nscreens
  4348.       \READ
  4349.       IF m.g_readcycle
  4350.          \\ CYCLE
  4351.       ENDIF
  4352.       DO anymodal
  4353.       DO anylock
  4354.       DO genreadclauses
  4355.       DO genwithclause
  4356.       DO gengivenread WITH m.scrnno
  4357.       _TEXT = m.g_tmphandle
  4358.       m.thispretext = _PRETEXT
  4359.       _PRETEXT = ""
  4360.       DO genclausecode WITH m.scrnno
  4361.       _TEXT = m.g_orghandle
  4362.       _PRETEXT = m.thispretext
  4363.    ENDIF
  4364. ENDIF
  4365. \
  4366. RETURN
  4367.  
  4368. *!*****************************************************************************
  4369. *!
  4370. *!      Procedure: ANYMODAL
  4371. *!
  4372. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4373. *!
  4374. *!*****************************************************************************
  4375. *)
  4376. *) ANYMODAL - Generate MODAL clause on READ.
  4377. *)
  4378. PROCEDURE anymodal
  4379. IF m.g_readmodal
  4380.    \\ MODAL
  4381. ENDIF
  4382. RETURN
  4383.  
  4384. *!*****************************************************************************
  4385. *!
  4386. *!      Procedure: ANYLOCK
  4387. *!
  4388. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4389. *!
  4390. *!*****************************************************************************
  4391. PROCEDURE anylock
  4392. *)
  4393. *) ANYLOCK - Generate LOCK/NOLOCK clause on READ.
  4394. *)
  4395. IF m.g_readlock
  4396.    \\ NOLOCK
  4397. ENDIF
  4398. RETURN
  4399.  
  4400. *!*****************************************************************************
  4401. *!
  4402. *!      Procedure: GENWITHCLAUSE
  4403. *!
  4404. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4405. *!
  4406. *!*****************************************************************************
  4407. PROCEDURE genwithclause
  4408. *)
  4409. *) GENWITHCLAUSE - Generate WITH clause on a READ.
  4410. *)
  4411. IF NOT EMPTY(m.g_withlist)
  4412.    \\ ;
  4413.    \    WITH <<m.g_withlist>>
  4414. ENDIF
  4415. RETURN
  4416.  
  4417. *!*****************************************************************************
  4418. *!
  4419. *!      Procedure: DOPLACECLAUSE
  4420. *!
  4421. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4422. *!
  4423. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4424. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4425. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4426. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4427. *!
  4428. *!*****************************************************************************
  4429. PROCEDURE doplaceclause
  4430. *)
  4431. *) DOPLACECLAUSE - Place READ level clauses for multiple reads.
  4432. *)
  4433. *) Description:
  4434. *) According to the read level clauses encoded in the screen file
  4435. *) set variables holding information about each clause.
  4436. *)
  4437. PARAMETER m.scrnno
  4438. PRIVATE thispretext
  4439. IF g_screens[m.scrnno, 6]
  4440.    LOCATE FOR objtype = c_otscreen
  4441. ELSE
  4442.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4443. ENDIF
  4444. IF NOT FOUND()
  4445.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4446.       LINENO(), c_error_3
  4447.    RETURN
  4448. ENDIF
  4449.  
  4450. DO findreadclauses WITH m.scrnno
  4451. DO genreadclauses
  4452. _TEXT = m.g_tmphandle
  4453. m.thispretext = _PRETEXT
  4454. _PRETEXT = ""
  4455.  
  4456. DO genclausecode WITH m.scrnno
  4457. _TEXT = m.g_orghandle
  4458. _PRETEXT = m.thispretext
  4459. RETURN
  4460.  
  4461. *!*****************************************************************************
  4462. *!
  4463. *!      Procedure: FINDREADCLAUSES
  4464. *!
  4465. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4466. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4467. *!
  4468. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4469. *!               : SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  4470. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  4471. *!
  4472. *!*****************************************************************************
  4473. PROCEDURE findreadclauses
  4474. *)
  4475. *) FINDREADCLAUSES - Find clauses for the final READ statement.
  4476. *)
  4477. *) Description:
  4478. *) Keep track of clauses that were already seen to determine what
  4479. *) clauses are placed on final read.  If this procedure is called for
  4480. *) a multiple read setting, flag's settings apply only to the current
  4481. *) screen.
  4482. *)
  4483. PARAMETER m.scrnno
  4484. PRIVATE m.dbalias, m.cur_rec
  4485. IF g_screens[m.scrnno,6]
  4486.    LOCATE FOR objtype = c_otscreen
  4487. ELSE
  4488.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4489. ENDIF
  4490. IF NOT FOUND()
  4491.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4492.       LINENO(), c_error_3
  4493.    RETURN
  4494. ENDIF
  4495.  
  4496. IF EMPTY(m.g_validtype) AND !EMPTY(VALID)
  4497.    DO setclauseflags WITH validtype, VALID, m.g_validname,;
  4498.       m.g_validtype
  4499. ENDIF
  4500. IF EMPTY(m.g_whentype) AND !EMPTY(WHEN)
  4501.    DO setclauseflags  WITH whentype, WHEN, m.g_whenname,;
  4502.       m.g_whentype
  4503. ENDIF
  4504. IF EMPTY(m.g_actitype) AND !EMPTY(ACTIVATE)
  4505.    DO setclauseflags WITH activtype, ACTIVATE, m.g_actiname,;
  4506.       m.g_actitype
  4507. ENDIF
  4508. IF EMPTY(m.g_deattype) AND !EMPTY(DEACTIVATE)
  4509.    DO setclauseflags WITH deacttype, DEACTIVATE, m.g_deatname,;
  4510.       m.g_deattype
  4511. ENDIF
  4512.  
  4513. * SHOW is a special case since it can be generated with both procedures (for refreshable
  4514. * SAYs or just regular procedures) and expressions.  OR the flags together.
  4515. IF !EMPTY(SHOW)
  4516.    IF showtype != c_genexpr
  4517.       DO orclauseflags WITH showtype, SHOW, m.g_showname, m.g_showtype
  4518.    ELSE
  4519.       m.cur_rec = RECNO()
  4520.       * It's an expression, but look for refreshable SAYs too.
  4521.       LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4522.          REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4523.       IF FOUND()
  4524.          GOTO m.cur_rec
  4525.          DO orclauseflags WITH c_genboth, SHOW,   m.g_showname, m.g_showtype
  4526.       ELSE
  4527.          GOTO m.cur_rec
  4528.          DO orclauseflags WITH c_genexpr, SHOW,   m.g_showname, m.g_showtype
  4529.       ENDIF
  4530.       m.g_showexpr = m.g_showname
  4531.    ENDIF
  4532. ELSE
  4533.    * Look for refreshable SAYS
  4534.    LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4535.       REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4536.    IF FOUND()
  4537.       DO orclauseflags WITH c_gencode, SHOW,   m.g_showname, m.g_showtype
  4538.    ENDIF
  4539. ENDIF
  4540. RETURN
  4541.  
  4542. *!*****************************************************************************
  4543. *!
  4544. *!      Procedure: SETCLAUSEFLAGS
  4545. *!
  4546. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4547. *!
  4548. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4549. *!
  4550. *!*****************************************************************************
  4551. PROCEDURE setclauseflags
  4552. *)
  4553. *) SETCLAUSEFLAGS - Load global flags with information about clauses.
  4554. *)
  4555. *) Description:
  4556. *) If a clause is a snippet then a generic name is provided for the
  4557. *) clause call statement in the READ and that same name is used to
  4558. *) construct the corresponding function.
  4559. *)
  4560. *) The BOTH setting is used for SHOW clauses that are defined as expressions,
  4561. *) in screens that also contain refreshable SAYS.  We have to generate a
  4562. *) procedure to contain the code to refresh the SAYS.
  4563. *)
  4564. PARAMETER m.flagtype, m.memo, m.name, m.type
  4565. DO CASE
  4566. CASE m.flagtype = c_genexpr
  4567.    m.name = m.memo
  4568.    m.type = "EXPR"
  4569. CASE m.flagtype = c_genboth
  4570.    m.name = m.memo
  4571.    m.type = "BOTH"
  4572. OTHERWISE
  4573.    m.name = getcname(m.memo)
  4574.    m.type = "CODE"
  4575. ENDCASE
  4576. RETURN
  4577.  
  4578. *!*****************************************************************************
  4579. *!
  4580. *!      Procedure: ORCLAUSEFLAGS
  4581. *!
  4582. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4583. *!
  4584. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4585. *!
  4586. *!*****************************************************************************
  4587. PROCEDURE orclauseflags
  4588. *)
  4589. *) ORCLAUSEFLAGS - Logical OR two flagtypes
  4590. *)
  4591. PARAMETER m.flagtype, m.memo, m.name, m.type
  4592. DO CASE
  4593. CASE m.flagtype = c_genexpr
  4594.    m.name = m.memo
  4595.    IF INLIST(m.type,"BOTH","CODE")
  4596.       m.type = "BOTH"
  4597.    ELSE
  4598.       m.type = "EXPR"
  4599.    ENDIF
  4600. CASE m.flagtype = c_genboth
  4601.    m.name = m.memo
  4602.    m.type = "BOTH"
  4603. OTHERWISE
  4604.    * Code of some sort.  The expr code is different for expanded snippets, closed snippets, etc.
  4605.    * It is 2 for expanded snippets and 3 for minimized snippets, for example.
  4606.    m.name = getcname(m.memo)
  4607.    IF INLIST(m.type,"BOTH","EXPR")
  4608.       m.type = "BOTH"
  4609.    ELSE
  4610.       m.type = "CODE"
  4611.    ENDIF
  4612. ENDCASE
  4613. RETURN
  4614.  
  4615. *!*****************************************************************************
  4616. *!
  4617. *!      Procedure: GENREADCLAUSES
  4618. *!
  4619. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4620. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4621. *!
  4622. *!          Calls: GENCLAUSE          (procedure in GENSCRN.PRG)
  4623. *!
  4624. *!*****************************************************************************
  4625. PROCEDURE genreadclauses
  4626. *)
  4627. *) GENREADCLAUSES - Generate Clauses on a READ.
  4628. *)
  4629. *) Description:
  4630. *) Check if clause is appropriate, if so call GENCLAUSE to
  4631. *) generate the clause keyword.
  4632. *)
  4633. IF NOT EMPTY(m.g_validtype)
  4634.    DO genclause WITH "VALID", m.g_validname, m.g_validtype
  4635. ENDIF
  4636. IF NOT EMPTY(m.g_whentype)
  4637.    DO genclause WITH "WHEN", m.g_whenname, m.g_whentype
  4638. ENDIF
  4639. IF NOT EMPTY(m.g_actitype)
  4640.    DO genclause WITH "ACTIVATE", m.g_actiname, m.g_actitype
  4641. ENDIF
  4642. IF NOT EMPTY(m.g_deattype)
  4643.    DO genclause WITH "DEACTIVATE", m.g_deatname, m.g_deattype
  4644. ENDIF
  4645. IF NOT EMPTY(m.g_showtype)
  4646.    DO genclause WITH "SHOW", m.g_showname, m.g_showtype, m.g_showexpr
  4647. ENDIF
  4648. RETURN
  4649.  
  4650. *!*****************************************************************************
  4651. *!
  4652. *!      Procedure: GENCLAUSE
  4653. *!
  4654. *!      Called by: GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4655. *!
  4656. *!*****************************************************************************
  4657. PROCEDURE genclause
  4658. *)
  4659. *) GENCLAUSE - Generate Read Level Clause keyword.
  4660. *)
  4661. *) Description:
  4662. *) Generate SHOW,ACTIVATE,WHEN, or VALID clause keyword for a
  4663. *) READ statement.
  4664. *)
  4665. PARAMETER m.keyword, m.name, m.type, m.expr
  4666. PRIVATE m.codename
  4667. \\ ;
  4668. \    <<m.keyword>>
  4669. DO CASE
  4670. CASE m.type = "CODE"
  4671.    \\ <<m.name>>
  4672.    \\()
  4673. CASE m.type = "EXPR"
  4674.    \\ <<stripCR(m.name)>>
  4675. CASE m.type = "BOTH"
  4676.    * This is tricky.  We need to generate the user's expression followed by
  4677.    * a procedure, presumably containing code to handle refreshable SAYS in
  4678.    * a READ ... SHOW clause.  Right now, the name variable contains the
  4679.    * expression.  Emit it, generate a random name for the SHOW snippet, then
  4680.    * record that random name in the m.name field so that we can remember it
  4681.    * later.  The expression needs to come second (due to the boolean short-cutting
  4682.    * optimization in the interpreter).
  4683.    IF EMPTY(m.expr)
  4684.       m.codename = LOWER(SYS(2015))
  4685.       \\ <<m.codename>>() AND (<<stripCR(m.name)>>)
  4686.       m.name     = m.codename
  4687.    ELSE
  4688.       * There was an explicit expression passed to us.  Use it.
  4689.       m.codename = LOWER(SYS(2015))
  4690.       \\ <<m.codename>>() AND (<<stripCR(m.expr)>>)
  4691.       m.name     = m.codename
  4692.    ENDIF
  4693. ENDCASE
  4694. RETURN
  4695.  
  4696. *!*****************************************************************************
  4697. *!
  4698. *!      Procedure: GENGIVENREAD
  4699. *!
  4700. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4701. *!
  4702. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4703. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4704. *!
  4705. *!*****************************************************************************
  4706. PROCEDURE gengivenread
  4707. *)
  4708. *) GENGIVENREAD - Generate another clause on the READ.
  4709. *)
  4710. PARAMETER m.screen
  4711. PRIVATE m.i, m.dbalias
  4712. IF m.g_multreads
  4713.    DO seekheader WITH m.screen
  4714.  
  4715.    IF ATC('#READ',setupcode) <> 0
  4716.       DO gendirective WITH ;
  4717.          MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4718.    ENDIF
  4719. ELSE
  4720.    FOR m.i = 1 TO m.g_nscreens
  4721.       m.g_screen = m.i
  4722.       m.dbalias = g_screens[m.i,5]
  4723.       SELECT (m.dbalias)
  4724.       DO seekheader WITH m.i
  4725.  
  4726.       IF ATC('#READ',setupcode)<>0
  4727.          DO gendirective WITH ;
  4728.             MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4729.          RETURN
  4730.       ENDIF
  4731.    ENDFOR
  4732.    m.g_screen = 0
  4733. ENDIF
  4734. RETURN
  4735.  
  4736. *!*****************************************************************************
  4737. *!
  4738. *!      Procedure: GENDIRECTIVE
  4739. *!
  4740. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4741. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4742. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  4743. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  4744. *!
  4745. *!          Calls: SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  4746. *!
  4747. *!*****************************************************************************
  4748. PROCEDURE gendirective
  4749. *)
  4750. *) GENDIRECTIVE - Process #ITSEXPRESSION, #READCLAUSES generator directives.
  4751. *)
  4752. PARAMETER m.line, m.directive
  4753. PRIVATE m.newline
  4754. IF ATC(m.directive,m.line)=1
  4755.    IF UPPER(m.directive) = '#REDE'
  4756.       m.g_redefi = .T.
  4757.       RETURN
  4758.    ENDIF
  4759.    m.newline = skipwhitespace(m.line)
  4760.    IF NOT EMPTY(m.newline)
  4761.       DO CASE
  4762.       CASE UPPER(m.directive) = '#READ'
  4763.          \\ ;
  4764.          \    <<UPPER(m.newline)>>
  4765.       CASE UPPER(m.directive) = '#WCLA'
  4766.          \\ ;
  4767.          \    <<UPPER(m.newline)>>
  4768.       CASE UPPER(m.directive) = '#ITSE'
  4769.          m.g_itse = SUBSTR(m.newline,1,1)
  4770.       ENDCASE
  4771.    ENDIF
  4772. ENDIF
  4773. RETURN
  4774.  
  4775. *!*****************************************************************************
  4776. *!
  4777. *!       Function: SKIPWHITESPACE
  4778. *!
  4779. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  4780. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4781. *!
  4782. *!*****************************************************************************
  4783. FUNCTION skipwhitespace
  4784. *)
  4785. *) SKIPWHITESPACE - Trim all white space from parameter string.
  4786. *)
  4787. PARAMETER m.line
  4788. PRIVATE m.whitespace
  4789. m.whitespace = AT(' ',m.line)
  4790. IF m.whitespace = 0
  4791.    m.whitespace = AT(CHR(9),m.line)
  4792. ENDIF
  4793. m.line = ALLTRIM(SUBSTR(m.line,m.whitespace))
  4794. DO WHILE SUBSTR(m.line,1,1) = CHR(9)
  4795.    m.line = ALLTRIM(SUBSTR(m.line, 2))
  4796. ENDDO
  4797. RETURN m.line
  4798.  
  4799. **
  4800. ** Code Generating Various Screen Objects
  4801. **
  4802.  
  4803. *!*****************************************************************************
  4804. *!
  4805. *!      Procedure: DEFPOPUPS
  4806. *!
  4807. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4808. *!
  4809. *!          Calls: GENPOPDEFI         (procedure in GENSCRN.PRG)
  4810. *!
  4811. *!*****************************************************************************
  4812. PROCEDURE defpopups
  4813. *)
  4814. *) DEFPOPUPS - Define popups used in scrollable list definition.
  4815. *)
  4816. *) Description:
  4817. *) Define popup which is later used in the definition of a
  4818. *) scrollable list.
  4819. *)
  4820. PRIVATE m.i, m.dbalias, m.cnt, m.anylists
  4821. m.cnt = 0
  4822. FOR m.i = 1 TO m.g_nscreens
  4823.    m.g_screen = m.i
  4824.    m.anylists = .F.
  4825.    m.dbalias = g_screens[m.i,5]
  4826.    SELECT (m.dbalias)
  4827.    SCAN FOR objtype = c_otlist AND STYLE > 1 AND ;
  4828.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4829.       IF NOT m.anylists
  4830.          \
  4831.          \#REGION <<INT(m.i)>>
  4832.          m.anylists = .T.
  4833.          m.g_somepops = .T.
  4834.       ENDIF
  4835.       m.cnt = m.cnt + 1
  4836.       g_popups[m.cnt,1] = m.dbalias
  4837.       g_popups[m.cnt,2] = RECNO()
  4838.       g_popups[m.cnt,3] = LOWER(SYS(2015))
  4839.  
  4840.       IF MOD(m.cnt,25)=0
  4841.          DIMENSION g_popups[ALEN(g_popups,1)+25,3]
  4842.       ENDIF
  4843.  
  4844.       DO genpopdefi
  4845.    ENDSCAN
  4846. ENDFOR
  4847. m.g_screen = 0
  4848. RETURN
  4849.  
  4850. *!*****************************************************************************
  4851. *!
  4852. *!      Procedure: GENPOPDEFI
  4853. *!
  4854. *!      Called by: DEFPOPUPS          (procedure in GENSCRN.PRG)
  4855. *!
  4856. *!*****************************************************************************
  4857. PROCEDURE genpopdefi
  4858. *)
  4859. *) GENPOPDEFI
  4860. *)
  4861. IF m.g_noreadplain
  4862.    RETURN
  4863. ENDIF
  4864.    
  4865. \DEFINE POPUP <<g_popups[m.cnt,3]>> ;
  4866. DO CASE
  4867. CASE STYLE = 2
  4868.    \    PROMPT STRUCTURE
  4869. CASE STYLE = 3
  4870.    \    PROMPT FIELD <<ALLTRIM(Expr)>>
  4871. CASE STYLE = 4
  4872.    \    PROMPT FILES
  4873.    IF NOT EMPTY(expr)
  4874.       \\ LIKE <<ALLTRIM(Expr)>>
  4875.    ENDIF
  4876. ENDCASE
  4877. \\ ;
  4878. \    SCROLL
  4879. IF m.g_genvers = 'DOS' OR m.g_genvers = 'UNIX'
  4880.    \\ ;
  4881.    \    MARGIN ;
  4882.    \    MARK ""
  4883.    \
  4884. ENDIF
  4885. RETURN
  4886.  
  4887. *!*****************************************************************************
  4888. *!
  4889. *!      Procedure: RELPOPUPS
  4890. *!
  4891. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  4892. *!
  4893. *!*****************************************************************************
  4894. PROCEDURE relpopups
  4895. *)
  4896. *) RELPOPUPS - Generate code to release generated popups.
  4897. *)
  4898. *) Description:
  4899. *) Generate code to release all popups defined by the generator
  4900. *) in conjunction with generating scrollable lists.
  4901. *)
  4902. PRIVATE m.popcnt, m.i, m.margin
  4903. m.popcnt = ALEN(g_popups,1)
  4904. m.margin = 16
  4905.  
  4906. IF EMPTY(g_popups[1,1]) OR m.g_noreadplain
  4907.    RETURN
  4908. ENDIF
  4909.  
  4910. \RELEASE POPUPS <<g_popups[1,3]>>
  4911. m.i = 2
  4912. DO WHILE m.i <= m.popcnt
  4913.    IF EMPTY(g_popups[m.i,1])
  4914.       RETURN
  4915.    ENDIF
  4916.    IF m.margin > 60
  4917.       m.margin = 4
  4918.       \\,;
  4919.       \    <<g_popups[m.i,3]>>
  4920.    ELSE
  4921.       \\, <<g_popups[m.i,3]>>
  4922.    ENDIF
  4923.    m.margin = m.margin + 3 + LEN(g_popups[m.i,3])
  4924.    m.i = m.i + 1
  4925. ENDDO
  4926. \
  4927. RETURN
  4928.  
  4929. *!*****************************************************************************
  4930. *!
  4931. *!      Procedure: DEFWINDOWS
  4932. *!
  4933. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4934. *!
  4935. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4936. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4937. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  4938. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  4939. *!
  4940. *!*****************************************************************************
  4941. PROCEDURE defwindows
  4942. *)
  4943. *) DEFWINDOWS - Generate code for windows.
  4944. *)
  4945. *) Description:
  4946. *) Generate code to define windows designed in the screen builder.
  4947. *) Process all SCX databases and if window definitions found
  4948. *) call GENWINDEFI to define the windows.
  4949. *)
  4950. PRIVATE m.dbalias, m.pos, m.savearea, m.row, m.col, m.firstfound, m.i
  4951. m.firstfound = .T.
  4952. m.savearea = SELECT()
  4953. FOR m.i = 1 TO m.g_nscreens
  4954.    m.g_screen = m.i
  4955.    m.dbalias = g_screens[m.i,5]
  4956.    SELECT (m.dbalias)
  4957.  
  4958.    SCAN FOR objtype = c_otscreen AND ;
  4959.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4960.  
  4961.       IF m.firstfound AND !m.g_noreadplain
  4962.          DO commentblock WITH ""," Window definitions"
  4963.          m.firstfound = .F.
  4964.       ENDIF
  4965.  
  4966.       IF NOT EMPTY(STYLE)
  4967.          IF ATC('#ITSE',setupcode)<>0
  4968.             DO gendirective WITH ;
  4969.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  4970.          ENDIF
  4971.          IF ATC('#REDE',setupcode)<>0
  4972.             DO gendirective WITH ;
  4973.                MLINE(setupcode,ATCLINE('#REDE',setupcode)),'#REDE'
  4974.          ENDIF
  4975.          DO genwindefi WITH m.i
  4976.       ELSE
  4977.          IF ATC('#ITSE',setupcode)<>0
  4978.             DO gendirective WITH ;
  4979.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  4980.          ENDIF
  4981.          DO gendesktop WITH m.i
  4982.       ENDIF
  4983.    ENDSCAN
  4984. ENDFOR
  4985. m.g_screen = 0
  4986. SELECT (m.savearea)
  4987. RETURN
  4988.  
  4989. *!*****************************************************************************
  4990. *!
  4991. *!      Procedure: GENDESKTOP
  4992. *!
  4993. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  4994. *!
  4995. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  4996. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  4997. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  4998. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  4999. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5000. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5001. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5002. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5003. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5004. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5005. *!
  5006. *!*****************************************************************************
  5007. PROCEDURE gendesktop
  5008. *)
  5009. *) GENDESKTOP - Generate statements to change the desktop font
  5010. *)
  5011. *) Description:
  5012. *) Generate code to change the desktop font if this screen is on
  5013. *) the desktop.  This is done only if the user chose the define window
  5014. *) option in the generate dialog.
  5015. *)
  5016. PARAMETER m.g_screen
  5017. PRIVATE m.center_flag, m.arrange_flag, m.row, m.col, m.j, m.entries
  5018.  
  5019. IF (g_screens[m.g_screen, 7] != 'WINDOWS' AND g_screens[m.g_screen, 7] != 'MAC')
  5020.    RETURN
  5021. ENDIF
  5022.  
  5023. m.center_flag = .F.
  5024. m.arrange_flag = .F.
  5025.  
  5026. IF NOT m.g_defwin
  5027.    RETURN
  5028. ENDIF
  5029.  
  5030. m.g_moddesktop = .T.
  5031.  
  5032. \MODIFY WINDOW SCREEN ;
  5033.  
  5034. IF g_screens[m.g_screen,6]
  5035.    DO windowfromto
  5036.    IF m.g_genvers = "WINDOWS" OR m.g_genvers = "MAC"
  5037.       \\ ;
  5038.       \    FONT "FoxFont", 9
  5039.    ENDIF
  5040. ELSE
  5041.    SELECT (m.g_projalias)
  5042.    GOTO RECORD g_screens[m.g_screen,3]
  5043.  
  5044.    DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5045.  
  5046.    DO anytitleorfooter
  5047.    DO anyfont
  5048.    DO anystyle
  5049.    DO anywindowchars
  5050.    DO anyborder
  5051.  
  5052.    IF  !EMPTY(PICTURE)
  5053.       DO anywallpaper
  5054.    ELSE
  5055.       DO anyscheme
  5056.    ENDIF
  5057.    DO anyicon
  5058.  
  5059.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5060.       \MOVE WINDOW SCREEN CENTER
  5061.    ENDIF
  5062. ENDIF
  5063. \CLEAR
  5064. RETURN
  5065.  
  5066. *!*****************************************************************************
  5067. *!
  5068. *!      Procedure: GENWINDEFI
  5069. *!
  5070. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  5071. *!
  5072. *!          Calls: UNIQUEWIN()        (function  in GENSCRN.PRG)
  5073. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  5074. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  5075. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5076. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5077. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5078. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5079. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5080. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5081. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5082. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5083. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  5084. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  5085. *!
  5086. *!*****************************************************************************
  5087. PROCEDURE genwindefi
  5088. *)
  5089. *) GENWINDEFI - Generate window definition
  5090. *)
  5091. *) Description:
  5092. *) Check to see if window name is unique, if not provide a unique name
  5093. *) with the use of SYS(2015) and display a warning message if
  5094. *) appropriate.  The window definition is generated only if the
  5095. *) user selected that option in the generator dialog.
  5096. *)
  5097. PARAMETER m.g_screen
  5098. PRIVATE m.name, m.pos, m.dupname, m.arrange_flag, m.center_flag, m.in_parms, m.j
  5099. m.arrange_flag = .F.
  5100. m.center_flag = .F.
  5101. m.dupname = .F.
  5102. m.name = IIF(!EMPTY(g_screens[m.g_screen,2]), g_screens[m.g_screen,2], LOWER(SYS(2015)))
  5103. m.pos = uniquewin(LOWER(m.name), m.g_nwindows, @g_wndows)
  5104. IF m.pos = 0
  5105.    m.dupname = .T.
  5106.    m.name = LOWER(SYS(2015))
  5107.    g_screens[m.g_screen,2] = m.name
  5108.    m.pos = uniquewin(m.name, m.g_nwindows, @g_wndows)
  5109. ENDIF
  5110.  
  5111. * Insert one row (two elements)
  5112. = AINS(g_wndows, m.pos)
  5113. g_wndows[m.pos,1] = m.name
  5114. g_wndows[m.pos,2] = .F.  && it will get a sequence number in AnyWindows
  5115. m.g_nwindows = m.g_nwindows + 1
  5116.  
  5117. m.g_windows = .T.
  5118. IF NOT m.g_defwin
  5119.    RETURN
  5120. ENDIF
  5121.  
  5122. IF NOT m.g_redefi
  5123.    \IF NOT WEXIST("<<m.name>>")
  5124.    * We can safely omit this extra code if the name was a randomly generated one
  5125.    IF  UPPER(LEFT(m.name,2)) <> UPPER(LEFT(SYS(2015),2))
  5126.       \\ ;
  5127.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PJX'))>>" ;
  5128.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'SCX'))>>" ;
  5129.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'MNX'))>>" ;
  5130.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PRG'))>>" ;
  5131.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'FRX'))>>" ;
  5132.       \    OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'QPR'))>>"
  5133.    ENDIF
  5134.    DO pushindent
  5135. ENDIF
  5136. \DEFINE WINDOW <<m.name>> ;
  5137.  
  5138. SELECT (m.g_projalias)
  5139. GOTO RECORD g_screens[m.g_screen,3]
  5140.  
  5141. DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5142.  
  5143. DO anytitleorfooter
  5144. DO anyfont
  5145. DO anystyle
  5146. DO anywindowchars
  5147. DO anyborder
  5148.  
  5149. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5150.    IF TAB
  5151.       \\ ;
  5152.       \    HALFHEIGHT
  5153.    ENDIF
  5154.    IF  !EMPTY(PICTURE)
  5155.       DO anywallpaper
  5156.    ELSE
  5157.       DO anyscheme
  5158.    ENDIF
  5159.    DO anyicon
  5160. ELSE
  5161.    DO anyscheme
  5162. ENDIF
  5163.  
  5164. * If the user defined additional window clauses, put them here
  5165. IF ATC("#WCLA",setupcode) > 0
  5166.    DO gendirective WITH ;
  5167.       MLINE(setupcode,ATCLINE('#WCLA',setupcode)),'#WCLA'
  5168. ENDIF
  5169.  
  5170. * Emit the MOVE WINDOW ... CENTER after all the window clauses have been emitted
  5171. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5172.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5173.       \MOVE WINDOW <<m.name>> CENTER
  5174.    ENDIF
  5175. ENDIF
  5176.  
  5177. IF !m.g_redefi
  5178.    DO popindent
  5179.    \ENDIF
  5180. ENDIF
  5181. \
  5182. RETURN
  5183.  
  5184. *!*****************************************************************************
  5185. *!
  5186. *!      Procedure: GETARRANGE
  5187. *!
  5188. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  5189. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  5190. *!
  5191. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  5192. *!
  5193. *!*****************************************************************************
  5194. PROCEDURE getarrange
  5195. PARAMETER m.dbalias, m.arrange_flag, m.center_flag
  5196. PRIVATE m.j, m.pname, m.entries, m.row, m.col
  5197. IF !EMPTY(arranged)
  5198.    m.entries = INT(LEN(arranged)/26)
  5199.    m.j = 1
  5200.    DO WHILE m.j <= m.entries
  5201.       m.pname = ALLTRIM(UPPER(SUBSTR(arranged,(m.j-1)*26+1,8)))
  5202.       m.pname = ALLTRIM(CHRTRAN(m.pname,CHR(0)," "))
  5203.       IF m.pname == m.g_genvers    && found the right one
  5204.          IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 + 9,1)),'Y','T')    && is it arranged?
  5205.             IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 +10,1)),'Y','T') && is it centered?
  5206.                m.center_flag = .T.
  5207.             ELSE
  5208.                m.arrange_flag = .T.
  5209.                m.row = VAL(SUBSTR(arranged,(m.j-1)*26 + 11,8))
  5210.                m.col = VAL(SUBSTR(arranged,(m.j-1)*26 + 19,8))
  5211.             ENDIF
  5212.          ENDIF
  5213.          EXIT
  5214.       ENDIF
  5215.       m.j = m.j + 1
  5216.    ENDDO
  5217. ENDIF
  5218. SELECT (m.dbalias)
  5219. IF m.arrange_flag
  5220.    DO windowfromto WITH m.row, m.col
  5221. ELSE
  5222.    DO windowfromto
  5223. ENDIF
  5224. RETURN
  5225.  
  5226. *!*****************************************************************************
  5227. *!
  5228. *!      Procedure: GENBOXES
  5229. *!
  5230. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5231. *!
  5232. *!          Calls: ANYPATTERN         (procedure in GENSCRN.PRG)
  5233. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5234. *!               : ANYPEN             (procedure in GENSCRN.PRG)
  5235. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5236. *!
  5237. *!*****************************************************************************
  5238. PROCEDURE genboxes
  5239. *)
  5240. *) GENBOXES - Generate code for boxes.
  5241. *)
  5242. *) Description:
  5243. *) Generate code to display all boxes as they appear on the painted
  5244. *) screen(s).  Note since there is no FILL clause on @...TO command
  5245. *) we use the command @...BOX whenever the fill option has been chosen.
  5246. *) If Fill option is not chosen, then we use the simpler form for
  5247. *) generating boxes, @...TO command which supplies us with clauses
  5248. *) DOUBLE and PANEL for the box borders.
  5249. *)
  5250. PRIVATE m.bottom, m.right, m.thisbox
  5251. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5252.    SET DECIMALS TO 3
  5253.    m.bottom = HEIGHT+vpos
  5254.    m.right = WIDTH+hpos
  5255. ELSE
  5256.    m.bottom = HEIGHT+vpos-1
  5257.    m.right = WIDTH+hpos-1
  5258. ENDIF
  5259. IF (m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC')
  5260.    IF fillchar <> c_null AND fillchar <> " "
  5261.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5262.       DO CASE
  5263.       CASE objcode = c_sgbox
  5264.          m.thisbox = c_single
  5265.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5266.       CASE objcode = c_sgboxd
  5267.          m.thisbox = c_double
  5268.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5269.       CASE objcode = c_sgboxp
  5270.          m.thisbox = c_panel
  5271.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5272.       CASE objcode = c_sgboxc
  5273.          IF boxchar = '"'
  5274.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5275.          ELSE
  5276.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5277.          ENDIF
  5278.          IF fillchar = '"'
  5279.             \\+'<<Fillchar>>'
  5280.          ELSE
  5281.             \\+"<<Fillchar>>"
  5282.          ENDIF
  5283.       ENDCASE
  5284.       SET DECIMALS TO 0
  5285.       RETURN
  5286.    ELSE
  5287.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5288.    ENDIF
  5289. ELSE
  5290.    IF fillchar <> c_null
  5291.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5292.       DO CASE
  5293.       CASE objcode = c_sgbox
  5294.          m.thisbox = c_single
  5295.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5296.       CASE objcode = c_sgboxd
  5297.          m.thisbox = c_double
  5298.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5299.       CASE objcode = c_sgboxp
  5300.          m.thisbox = c_panel
  5301.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5302.       CASE objcode = c_sgboxc
  5303.          IF boxchar = '"'
  5304.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5305.          ELSE
  5306.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5307.          ENDIF
  5308.          IF fillchar = '"'
  5309.             \\+'<<Fillchar>>'
  5310.          ELSE
  5311.             \\+"<<Fillchar>>"
  5312.          ENDIF
  5313.       ENDCASE
  5314.  
  5315.       IF (!EMPTY(colorpair) OR SCHEME <> 0)
  5316.          * Color the inside of the box if it is filled with something.
  5317.          \@ <<Vpos>>,<<Hpos>> FILL TO <<m.bottom>>,<<m.right>>
  5318.          DO anypattern
  5319.          DO anyscheme
  5320.       ENDIF
  5321.       SET DECIMALS TO 0
  5322.       RETURN
  5323.    ELSE
  5324.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5325.    ENDIF
  5326. ENDIF
  5327.  
  5328. SET DECIMALS TO 0
  5329. DO CASE
  5330. CASE objcode = c_sgboxd
  5331.    \\ DOUBLE
  5332. CASE objcode = c_sgboxp
  5333.    \\ PANEL
  5334. CASE objcode = c_sgboxc
  5335.    IF boxchar = '"'
  5336.       \\ '<<Boxchar>>'
  5337.    ELSE
  5338.       \\ "<<Boxchar>>"
  5339.    ENDIF
  5340. ENDCASE
  5341. DO anypattern
  5342. DO anypen
  5343. DO anystyle
  5344. DO anyscheme
  5345. RETURN
  5346.  
  5347. *!*****************************************************************************
  5348. *!
  5349. *!      Procedure: GENLINES
  5350. *!
  5351. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5352. *!
  5353. *!          Calls: ANYPEN             (procedure in GENSCRN.PRG)
  5354. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5355. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5356. *!
  5357. *!*****************************************************************************
  5358. PROCEDURE genlines
  5359. *)
  5360. *) GENLINES - Generate code for lines.
  5361. *)
  5362. *) Description:
  5363. *) Generate code to display all lines as they appear on the painted
  5364. *) screen(s).
  5365. *)
  5366. PRIVATE m.x, m.y
  5367. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5368.    SET DECIMALS TO 3
  5369.    IF STYLE = 0
  5370.       m.x = HEIGHT+vpos
  5371.       m.y = hpos
  5372.    ELSE
  5373.       m.x = vpos
  5374.       m.y = WIDTH+hpos
  5375.    ENDIF
  5376. ELSE
  5377.    m.x = HEIGHT+vpos-1
  5378.    m.y = WIDTH+hpos-1
  5379. ENDIF
  5380.  
  5381. \@ <<Vpos>>,<<Hpos>> TO <<m.x>>,<<m.y>>
  5382. SET DECIMALS TO 0
  5383. IF BORDER = 1
  5384.    \\ DOUBLE
  5385. ENDIF
  5386. DO anypen
  5387. DO anystyle
  5388. DO anyscheme
  5389. RETURN
  5390.  
  5391.  
  5392. *!*****************************************************************************
  5393. *!
  5394. *!      Procedure: GENTEXT
  5395. *!
  5396. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5397. *!
  5398. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5399. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5400. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5401. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5402. *!
  5403. *!*****************************************************************************
  5404. PROCEDURE gentext
  5405. *)
  5406. *) GENTEXT - Generate code for text.
  5407. *)
  5408. *) Description:
  5409. *) Generate code that will display the text exactly as it appears
  5410. *) in the painted screen(s).
  5411. *)
  5412. PRIVATE m.theexpr, m.occur, m.pos
  5413. m.theexpr = expr
  5414. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5415.    SET DECIMALS TO 3
  5416.    m.occur = 1
  5417.    m.pos = AT(CHR(13), m.theexpr, m.occur)
  5418.    * Sometimes the screen builder surrounds text with single quotes and other
  5419.    * times with double quotes.
  5420.    q1 = LEFT(LTRIM(m.theexpr),1)
  5421.  
  5422.    DO WHILE m.pos > 0
  5423.       DO CASE
  5424.       CASE q1 = "'"
  5425.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5426.             "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  5427.             + SUBSTR(m.theexpr, m.pos + 1)
  5428.       CASE q1 = '['
  5429.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5430.             "] + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "[" ;
  5431.             + SUBSTR(m.theexpr, m.pos + 1)
  5432.       OTHERWISE
  5433.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5434.             '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  5435.             + SUBSTR(m.theexpr, m.pos + 1)
  5436.       ENDCASE
  5437.       m.occur = m.occur + 1
  5438.       m.pos = AT(CHR(13), m.theexpr, m.occur)
  5439.    ENDDO
  5440.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> 
  5441.    IF height > 1
  5442.       \\ ;
  5443.       \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5444.    ENDIF
  5445. ELSE
  5446.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5447.    \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5448. ENDIF
  5449.  
  5450. SET DECIMALS TO 0
  5451. DO anypicture
  5452. DO anyfont
  5453. DO anystyle
  5454. DO anyscheme
  5455. RETURN
  5456.  
  5457. *!*****************************************************************************
  5458. *!
  5459. *!      Procedure: GENFIELDS
  5460. *!
  5461. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5462. *!
  5463. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5464. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5465. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  5466. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5467. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5468. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  5469. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5470. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5471. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5472. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5473. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5474. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5475. *!
  5476. *!*****************************************************************************
  5477. PROCEDURE genfields
  5478. *)
  5479. *) GENFIELDS - Generate fields.
  5480. *)
  5481. *) Description:
  5482. *) Generate code to display SAY, GET, and EDIT statements exactly as they
  5483. *) appear in the painted screen(s).
  5484. *)
  5485. PRIVATE m.theexpr
  5486. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5487.    SET DECIMALS TO 3
  5488. ENDIF
  5489. DO CASE
  5490. CASE objcode = c_sgsay
  5491.    m.theexpr = expr
  5492.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5493.    \    SIZE <<Height>>,<<Width>>
  5494.    SET DECIMALS TO 0
  5495.    DO anyfont
  5496.    DO anystyle
  5497.    DO anypicture
  5498.    DO anyscheme
  5499.    RETURN
  5500. CASE objcode = c_sgget
  5501.    \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5502.    \    SIZE <<Height>>,<<Width>>
  5503.    DO elemrange
  5504. CASE objcode = c_sgedit
  5505.    DO gentxtrgn
  5506.    RETURN
  5507. ENDCASE
  5508. SET DECIMALS TO 0
  5509.  
  5510. DO gendefault
  5511. DO anyfont
  5512. DO anystyle
  5513. DO anypicture
  5514. DO anywhen
  5515. DO anyvalid
  5516. DO anymessage
  5517. DO anyerror
  5518. DO anydisabled
  5519. DO anyscheme
  5520. RETURN
  5521.  
  5522. *!*****************************************************************************
  5523. *!
  5524. *!      Procedure: GENINVBUT
  5525. *!
  5526. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5527. *!
  5528. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5529. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5530. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5531. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5532. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5533. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5534. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5535. *!
  5536. *!*****************************************************************************
  5537. PROCEDURE geninvbut
  5538. *)
  5539. *) GENINVBUT - Generate Invisible buttons.
  5540. *)
  5541. *) Description:
  5542. *) Generate code to display invisible buttons exactly as they appear
  5543. *) in the painted screen(s).
  5544. *)
  5545.  
  5546. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5547.    SET DECIMALS TO 3
  5548. ENDIF
  5549. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5550. \    PICTURE <<Picture>> ;
  5551. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5552. \    DEFAULT 0
  5553. SET DECIMALS TO 0
  5554.  
  5555. DO anyfont
  5556. DO anystyle
  5557. DO anywhen
  5558. DO anyvalid
  5559. DO anydisabled
  5560. DO anymessage
  5561. DO anyscheme
  5562. RETURN
  5563.  
  5564. *!*****************************************************************************
  5565. *!
  5566. *!      Procedure: GENTXTRGN
  5567. *!
  5568. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  5569. *!
  5570. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5571. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5572. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5573. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5574. *!               : ANYTAB             (procedure in GENSCRN.PRG)
  5575. *!               : ANYSCROLL          (procedure in GENSCRN.PRG)
  5576. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5577. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5578. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5579. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5580. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5581. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5582. *!
  5583. *!*****************************************************************************
  5584. PROCEDURE gentxtrgn
  5585. *)
  5586. *) GENTXTRGN - Generate some statements for text edit region.
  5587. *)
  5588. *) Description:
  5589. *) Generate code to display text edit regions exactly as they
  5590. *) appear on the painted screen(s).
  5591. *)
  5592. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5593.    SET DECIMALS TO 3
  5594. ENDIF
  5595. \@ <<Vpos>>,<<Hpos>> EDIT <<Name>> ;
  5596. \    SIZE <<IIF(Height < 1, 1, Height)>>,<<Width>>,<<Initialnum>>
  5597. SET DECIMALS TO 0
  5598.  
  5599. IF NOT EMPTY(PICTURE)
  5600.    DO anypicture
  5601. ENDIF
  5602. DO gendefault
  5603. DO anyfont
  5604. DO anystyle
  5605. DO anytab
  5606. DO anyscroll
  5607. DO anywhen
  5608. DO anyvalid
  5609. DO anymessage
  5610. DO anyerror
  5611. DO anydisabled
  5612. DO anyscheme
  5613. RETURN
  5614.  
  5615. *!*****************************************************************************
  5616. *!
  5617. *!      Procedure: GENPUSH
  5618. *!
  5619. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5620. *!
  5621. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5622. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5623. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5624. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5625. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5626. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5627. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5628. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5629. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5630. *!
  5631. *!*****************************************************************************
  5632. PROCEDURE genpush
  5633. *)
  5634. *) GENPUSH - Generate Push buttons.
  5635. *)
  5636. *) Description:
  5637. *) Generate code to display push buttons exactly as they appear
  5638. *) in the painted screen(s).
  5639. *)
  5640. PRIVATE m.thepicture
  5641.  
  5642. m.thepicture = PICTURE
  5643. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5644.    SET DECIMALS TO 3
  5645. ENDIF
  5646. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5647. DO anybitmapctrl WITH m.thepicture
  5648. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5649. SET DECIMALS TO 0
  5650. \    DEFAULT <<Initialnum>>
  5651. DO anyfont
  5652. DO anystyle
  5653. DO anywhen
  5654. DO anyvalid
  5655. DO anydisabled
  5656. DO anymessage
  5657. DO anyerror
  5658. DO anyscheme
  5659. RETURN
  5660.  
  5661. *!*****************************************************************************
  5662. *!
  5663. *!      Procedure: GENRADBUT
  5664. *!
  5665. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5666. *!
  5667. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5668. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5669. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5670. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5671. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5672. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5673. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5674. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5675. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5676. *!
  5677. *!*****************************************************************************
  5678. PROCEDURE genradbut
  5679. *)
  5680. *) GENRADBUT - Generate Radio Buttons.
  5681. *)
  5682. *) Description:
  5683. *) Generate code to display radio buttons exactly as they appear
  5684. *) in the painted screen(s).
  5685. *)
  5686. PRIVATE m.thepicture
  5687.  
  5688. m.thepicture = PICTURE
  5689. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5690.    SET DECIMALS TO 3
  5691. ENDIF
  5692. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5693. DO anybitmapctrl WITH m.thepicture
  5694. \    SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5695. SET DECIMALS TO 0
  5696. \    DEFAULT <<Initialnum>>
  5697. DO anyfont
  5698. DO anystyle
  5699. DO anywhen
  5700. DO anyvalid
  5701. DO anydisabled
  5702. DO anymessage
  5703. DO anyerror
  5704. DO anyscheme
  5705. RETURN
  5706.  
  5707. *!*****************************************************************************
  5708. *!
  5709. *!      Procedure: GENCHKBOX
  5710. *!
  5711. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5712. *!
  5713. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5714. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5715. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5716. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5717. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5718. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5719. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5720. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5721. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5722. *!
  5723. *!*****************************************************************************
  5724. PROCEDURE genchkbox
  5725. *)
  5726. *) GENCHKBOX - Generate Check Boxes
  5727. *)
  5728. *) Description:
  5729. *) Generate code to display check boxes exactly as they appear
  5730. *) in the painted screen(s).
  5731. *)
  5732. PRIVATE m.thepicture
  5733.  
  5734. m.thepicture = PICTURE
  5735. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5736.    SET DECIMALS TO 3
  5737. ENDIF
  5738.  
  5739. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5740. DO anybitmapctrl WITH m.thepicture
  5741. \    SIZE <<Height>>,<<Width>> ;
  5742. SET DECIMALS TO 0
  5743. \    DEFAULT <<Initialnum>>
  5744. DO anyfont
  5745. DO anystyle
  5746. DO anywhen
  5747. DO anyvalid
  5748. DO anydisabled
  5749. DO anymessage
  5750. DO anyerror
  5751. DO anyscheme
  5752. RETURN
  5753.  
  5754. *!*****************************************************************************
  5755. *!
  5756. *!      Procedure: GENLIST
  5757. *!
  5758. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5759. *!
  5760. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5761. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5762. *!               : FROMPOPUP          (procedure in GENSCRN.PRG)
  5763. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5764. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5765. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5766. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5767. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5768. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5769. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5770. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5771. *!
  5772. *!*****************************************************************************
  5773. PROCEDURE genlist
  5774. *)
  5775. *) GENLIST - Generate Scrollable Lists.
  5776. *)
  5777. *) Description:
  5778. *) Generate code to display scrollable lists exactly as they appear
  5779. *) in the painted screen(s).
  5780. *)
  5781. PRIVATE m.pos, m.start
  5782. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5783.    SET DECIMALS TO 3
  5784. ENDIF
  5785. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5786. SET DECIMALS TO 0
  5787. IF NOT EMPTY(PICTURE)
  5788.    \     PICTURE
  5789.    DO choppicture WITH PICTURE
  5790.    \\ ;
  5791. ENDIF
  5792. IF STYLE = 0
  5793.    \    FROM <<Expr>>
  5794.    DO elemrange
  5795.    \\ ;
  5796.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5797.       SET DECIMALS TO 3
  5798.    ENDIF
  5799.    \    SIZE <<Height>>,<<Width>> ;
  5800.    SET DECIMALS TO 0
  5801.    \    DEFAULT 1
  5802. ELSE
  5803.    DO frompopup
  5804. ENDIF
  5805.  
  5806. DO anyfont
  5807. DO anystyle
  5808. DO anywhen
  5809. DO anyvalid
  5810. DO anydisabled
  5811. DO anymessage
  5812. DO anyerror
  5813. DO anyscheme
  5814. RETURN
  5815.  
  5816. *!*****************************************************************************
  5817. *!
  5818. *!      Procedure: GENPICTURE
  5819. *!
  5820. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  5821. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  5822. *!
  5823. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  5824. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5825. *!
  5826. *!*****************************************************************************
  5827. PROCEDURE genpicture
  5828. *)
  5829. *) GENPICTURE - Generate code for pictures.
  5830. *)
  5831. *) Description:
  5832. *) Generate code to display pictures (bitmaps or bitmaps in general fields).
  5833. *)
  5834. PRIVATE m.relpath
  5835. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5836.    SET DECIMALS TO 3
  5837.    \@ <<Vpos>>,<<Hpos>> SAY
  5838.    IF STYLE = 0
  5839.       m.relpath = LOWER(findrelpath(SUBSTR(PICTURE,2,LEN(PICTURE)-2)))
  5840.         IF EMPTY(justext(m.relpath))
  5841.            m.relpath = m.relpath + "."
  5842.         ENDIF
  5843.       \\ (LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>, "Where is <<basename(m.relpath)>>?"
  5844.         IF _MAC
  5845.             * Use the "type" parameter to get all PICT files on the Mac,
  5846.             * regardless of extension.
  5847.             \\, "PICT"
  5848.         ENDIF
  5849.         \\ )) BITMAP ;
  5850.    ELSE
  5851.       \\ <<Name>> ;
  5852.    ENDIF
  5853.    \    SIZE <<Height>>,<<Width>>
  5854.  
  5855.    IF CENTER
  5856.       \\ ;
  5857.       \    CENTER
  5858.    ENDIF
  5859.  
  5860.    DO CASE
  5861.    CASE BORDER = 1
  5862.       \\ ;
  5863.       \    ISOMETRIC
  5864.    CASE BORDER = 2
  5865.       \\ ;
  5866.       \    STRETCH
  5867.    ENDCASE
  5868.  
  5869.    SET DECIMALS TO 0
  5870.    DO anystyle
  5871. ENDIF
  5872. RETURN
  5873.  
  5874. *!*****************************************************************************
  5875. *!
  5876. *!      Procedure: GENSPINNER
  5877. *!
  5878. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5879. *!
  5880. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5881. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5882. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5883. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5884. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5885. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5886. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5887. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5888. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5889. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5890. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5891. *!
  5892. *!*****************************************************************************
  5893. PROCEDURE genspinner
  5894. *)
  5895. *) GENSPINNER - Generate Spinners
  5896. *)
  5897. *) Description:
  5898. *) Generate code to display spinners exactly as they appear
  5899. *) in the painted screen(s).
  5900. *)
  5901. PRIVATE m.thepicture
  5902.  
  5903. m.thepicture = PICTURE
  5904. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5905.    SET DECIMALS TO 3
  5906. ENDIF
  5907.  
  5908. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5909. \    SPINNER
  5910.  
  5911. ** Generate the increment value
  5912. IF !EMPTY(initialval)
  5913.    IF INT(VAL(initialval)) <> VAL(initialval)
  5914.       SET DECIMALS TO LEN(initialval) - AT('.',initialval)
  5915.    ENDIF
  5916.    \\ <<VAL(Initialval)>>
  5917.    SET DECIMALS TO 3
  5918. ELSE
  5919.    \\ 1.000
  5920. ENDIF
  5921.  
  5922. ** Generate the minimum value.
  5923. IF !EMPTY(TAG)
  5924.    \\, <<Tag>>
  5925. ELSE
  5926.    IF !EMPTY(tag2)
  5927.       \\,
  5928.    ENDIF
  5929. ENDIF
  5930.  
  5931. ** Generate the maximum value.
  5932. IF !EMPTY(tag2)
  5933.    \\, <<Tag2>>
  5934. ENDIF
  5935. \\ ;
  5936.  
  5937. IF !EMPTY(m.thepicture)
  5938.    \    PICTURE
  5939.    DO choppicture WITH m.thepicture
  5940.    \\ ;
  5941. ENDIF
  5942. \    SIZE <<Height>>, <<Width>>
  5943.  
  5944. ** Put out a default which corresponds to the range of valid values.
  5945. DO CASE
  5946. CASE !EMPTY(TAG)
  5947.    \\ ;
  5948.    \    DEFAULT <<VAL(Tag)>>
  5949. CASE !EMPTY(tag2)
  5950.    \\ ;
  5951.    \    DEFAULT <<VAL(Tag2)>>
  5952. CASE EMPTY(TRIM(initialval))
  5953.    \\ ;
  5954.    \    DEFAULT 1
  5955. OTHERWISE
  5956.    DO gendefault
  5957. ENDCASE
  5958.  
  5959. DO elemrange
  5960. DO anywhen
  5961. DO anyvalid
  5962. DO anydisabled
  5963. DO anymessage
  5964. DO anyerror
  5965. SET DECIMALS TO 0
  5966. DO anyfont
  5967. DO anystyle
  5968. DO anyscheme
  5969. RETURN
  5970.  
  5971. *!*****************************************************************************
  5972. *!
  5973. *!      Procedure: FROMPOPUP
  5974. *!
  5975. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  5976. *!
  5977. *!*****************************************************************************
  5978. PROCEDURE frompopup
  5979. *)
  5980. *) FROMPOPUP - Generate code for scrollable list defined from a popup.
  5981. *)
  5982. *) Description:
  5983. *) Generate POPUP <popup name> code as part of a scrollable list
  5984. *) definition.  Popup name may either be name explicitly provided by
  5985. *) the user or a unique name generated by SYS(2015) function.
  5986. *)
  5987. PRIVATE m.start, m.pos
  5988. \    POPUP
  5989. IF STYLE < 2
  5990.    IF NOT EMPTY(expr)
  5991.       \\ <<Expr>> ;
  5992.    ENDIF
  5993. ELSE
  5994.    m.start = 1
  5995.    m.pos   = 0
  5996.    DO WHILE .T.
  5997.       m.pos = ASCAN(g_popups, m.dbalias, m.start)
  5998.       IF g_popups[m.pos+1] = RECNO()
  5999.          EXIT
  6000.       ENDIF
  6001.       m.start = m.pos + 3
  6002.    ENDDO
  6003.    \\ <<g_popups[m.pos+2]>> ;
  6004. ENDIF
  6005.  
  6006. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6007.    SET DECIMALS TO 3
  6008. ENDIF
  6009. \    SIZE <<Height>>,<<Width>> ;
  6010. \    DEFAULT " "
  6011. SET DECIMALS TO 0
  6012. RETURN
  6013.  
  6014. *!*****************************************************************************
  6015. *!
  6016. *!      Procedure: GENPOPUP
  6017. *!
  6018. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  6019. *!
  6020. *!          Calls: ELEMRANGE          (procedure in GENSCRN.PRG)
  6021. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  6022. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  6023. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  6024. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  6025. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  6026. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  6027. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  6028. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  6029. *!
  6030. *!*****************************************************************************
  6031. PROCEDURE genpopup
  6032. *)
  6033. *) GENPOPUP - Generate Popups.
  6034. *)
  6035. *) Description:
  6036. *) Generate code to display popups exactly as they appear in the
  6037. *) painted screen(s).
  6038. *)
  6039. PRIVATE m.thepicture, m.theinitval
  6040.  
  6041. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6042.    SET DECIMALS TO 3
  6043. ENDIF
  6044. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  6045. IF objcode = c_sgget
  6046.    m.thepicture = PICTURE
  6047.    m.theinitval = initialval
  6048.    \    PICTURE <<m.thepicture>> ;
  6049.    \    SIZE <<Height>>,<<Width>> ;
  6050.    \    DEFAULT <<IIF(EMPTY(m.theinitval), '" "', m.theinitval)>>
  6051. ELSE
  6052.     * e.g., popup from array
  6053.    \    PICTURE "<<ctrlclause(picture)>>" ;
  6054.    \    FROM <<Expr>> ;
  6055.    \    SIZE <<Height>>,<<Width>>
  6056.    DO elemrange
  6057.    \\ ;
  6058.    \    DEFAULT 1
  6059. ENDIF
  6060. SET DECIMALS TO 0
  6061.  
  6062. DO anyfont
  6063. DO anystyle
  6064. DO anywhen
  6065. DO anyvalid
  6066. DO anydisabled
  6067. DO anymessage
  6068. DO anyerror
  6069. DO anyscheme
  6070. RETURN
  6071.  
  6072. *!*****************************************************************************
  6073. *!
  6074. *!      Procedure: ELEMRANGE
  6075. *!
  6076. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6077. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6078. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6079. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6080. *!
  6081. *!          Calls: ADDTOCTRL          (procedure in GENSCRN.PRG)
  6082. *!
  6083. *!*****************************************************************************
  6084. PROCEDURE elemrange
  6085. *)
  6086. *) ELEMRANGE - Element range clause for popup and scrollable list
  6087. *)                defined form an array.
  6088. *)
  6089. PRIVATE m.firstelem, m.genericname
  6090. m.firstelem = .F.
  6091. IF NOT EMPTY(rangelo)
  6092.    m.firstelem = .T.
  6093.    \\ ;
  6094.    \    RANGE
  6095.    IF lotype = 0
  6096.       \\ <<ALLTRIM(CHRTRAN(Rangelo,CHR(13)+CHR(10),""))>>
  6097.    ELSE
  6098.       m.genericname = LOWER(SYS(2015))
  6099.       \\ <<m.genericname>>()
  6100.       DO CASE
  6101.       CASE objtype = c_otfield
  6102.          DO addtoctrl WITH m.genericname, "GET Low RANGE", rangelo, name
  6103.       CASE objtype = c_otspinner
  6104.          DO addtoctrl WITH m.genericname, "SPINNER Low RANGE", rangelo, name
  6105.       OTHERWISE
  6106.          DO addtoctrl WITH m.genericname, "Popup From", rangelo, name
  6107.       ENDCASE
  6108.    ENDIF
  6109. ENDIF
  6110. IF NOT EMPTY(rangehi)
  6111.    IF NOT m.firstelem
  6112.       \\ ;
  6113.       \    RANGE ,
  6114.    ELSE
  6115.       \\,
  6116.    ENDIF
  6117.    IF hitype = 0
  6118.       \\ <<CHRTRAN(ALLTRIM(Rangehi),CHR(13)+CHR(10),"")>>
  6119.    ELSE
  6120.       m.genericname = LOWER(SYS(2015))
  6121.       \\ <<m.genericname>>()
  6122.       DO CASE
  6123.       CASE objtype = c_otfield
  6124.          DO addtoctrl WITH m.genericname, "GET High RANGE", rangehi, name
  6125.       CASE objtype = c_otspinner
  6126.          DO addtoctrl WITH m.genericname, "SPINNER High RANGE", rangehi, name
  6127.       OTHERWISE
  6128.          DO addtoctrl WITH m.genericname, "Popup From", rangehi, name
  6129.       ENDCASE
  6130.    ENDIF
  6131. ENDIF
  6132. RETURN
  6133.  
  6134. *!*****************************************************************************
  6135. *!
  6136. *!      Procedure: GENACTWINDOW
  6137. *!
  6138. *!      Called by: ANYWINDOWS         (procedure in GENSCRN.PRG)
  6139. *!
  6140. *!*****************************************************************************
  6141. PROCEDURE genactwindow
  6142. *)
  6143. *) GENACTWINDOW - Generate Activate Window Command.
  6144. *)
  6145. *) Description:
  6146. *) Generate the ACTIVATE WINDOW... command.
  6147. *)
  6148. PARAMETER m.cnt
  6149. IF !m.g_noreadplain
  6150.    IF m.g_lastwindow == g_screens[m.cnt,2]
  6151.       \@ 0,0 CLEAR
  6152.    ENDIF
  6153.    IF m.g_multreads
  6154.       \ACTIVATE WINDOW <<g_screens[m.cnt,2]>>
  6155.       RETURN
  6156.    ENDIF
  6157.    
  6158.    \IF WVISIBLE("<<g_screens[m.cnt,2]>>")
  6159.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> SAME
  6160.    \ELSE
  6161.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> NOSHOW
  6162.    \ENDIF
  6163. ENDIF
  6164. RETURN
  6165.  
  6166. *!*****************************************************************************
  6167. *!
  6168. *!      Procedure: GENDEFAULT
  6169. *!
  6170. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6171. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6172. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6173. *!
  6174. *!*****************************************************************************
  6175. PROCEDURE gendefault
  6176. *)
  6177. *) GENDEFAULT - Generate Default Clause.
  6178. *)
  6179. PRIVATE m.theinitval
  6180. IF EMPTY(TRIM(initialval)) AND EMPTY(fillchar)
  6181.    RETURN
  6182. ENDIF
  6183. \\ ;
  6184. \    DEFAULT
  6185. IF EMPTY(TRIM(initialval))
  6186.    DO CASE
  6187.    CASE fillchar = "D"
  6188.       \\ {  /  /  }
  6189.    CASE fillchar = "C" OR fillchar = "M" OR fillchar = "G"
  6190.       \\ " "
  6191.    CASE fillchar = "L"
  6192.       \\ .F.
  6193.    CASE fillchar = "N"
  6194.       \\ 0
  6195.    CASE fillchar = "F"
  6196.       \\ 0.0
  6197.    ENDCASE
  6198. ELSE
  6199.    m.theinitval = initialval
  6200.    \\ <<ALLTRIM(m.theinitval)>>
  6201. ENDIF
  6202. RETURN
  6203.  
  6204. **
  6205. **  Procedures Generating Various Clauses for Screen Objects
  6206. **
  6207.  
  6208. *!*****************************************************************************
  6209. *!
  6210. *!      Procedure: ANYBITMAPCTRL
  6211. *!
  6212. *!      Called by: GENPUSH            (procedure in GENSCRN.PRG)
  6213. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6214. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6215. *!
  6216. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6217. *!               : CHOPPICTURE        (procedure in GENSCRN.PRG)
  6218. *!
  6219. *!*****************************************************************************
  6220. PROCEDURE anybitmapctrl
  6221. *)
  6222. *) ANYBITMAPCTRL - Parse the picture clause for a bitmap control (Push button, radio button, checkbox) and return it
  6223. *)        with LOCAFILE and a relative path in place of each absolute path.
  6224. *)
  6225. PARAMETER m.picture
  6226. PRIVATE m.name, m.relpath, m.count
  6227.  
  6228. IF AT("B", SUBSTR(m.picture,1, AT(" ",m.picture))) <> 0
  6229.    \    PICTURE <<LEFT(m.picture, AT(" ",m.picture))>>"
  6230.  
  6231.    m.picture = SUBSTR(m.picture, AT(" ", m.picture)+1)
  6232.    m.picture = LEFT(m.picture, LEN(m.picture)-1)
  6233.    m.count = 0
  6234.  
  6235.    DO WHILE LEN(m.picture) <> 0
  6236.       m.count = m.count + 1
  6237.       IF AT(";", m.picture) <> 0
  6238.          m.name = LEFT(m.picture, AT(";", m.picture)-1)
  6239.          m.picture = SUBSTR(m.picture, AT(";",m.picture)+1)
  6240.       ELSE
  6241.          m.name = m.picture
  6242.          m.picture = ""
  6243.       ENDIF
  6244.  
  6245.       m.relpath = LOWER(findrelpath(m.name))
  6246.  
  6247.       IF m.count = 1
  6248.          \\ + ;
  6249.       ELSE
  6250.          \\ + ";" + ;
  6251.       ENDIF
  6252.         IF EMPTY(justext(m.relpath))
  6253.            m.relpath = m.relpath + "."
  6254.         ENDIF
  6255.       \        (LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>,"Where is <<basename(m.relpath)>>?"
  6256.         IF _MAC
  6257.             \\,"PICT"
  6258.         ENDIF
  6259.         \\))
  6260.    ENDDO
  6261.  
  6262.    \\ ;
  6263. ELSE
  6264.    \    PICTURE
  6265.    DO choppicture WITH m.picture
  6266.    \\ ;
  6267. ENDIF
  6268. RETURN
  6269.  
  6270. *!*****************************************************************************
  6271. *!
  6272. *!      Procedure: CHOPPICTURE
  6273. *!
  6274. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  6275. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6276. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  6277. *!
  6278. *!*****************************************************************************
  6279. PROCEDURE choppicture
  6280. *)
  6281. *) CHOPPICTURE - Breaks a Picture clause into multiple 250 character segments to avoid
  6282. *)        the maximum string length limit.
  6283. *)
  6284. PARAMETER m.pict
  6285. PRIVATE m.quotechar, m.first
  6286. m.quotechar = LEFT(m.pict,1)
  6287. m.first = .T.
  6288.  
  6289. DO WHILE LEN(m.pict) > 250
  6290.    IF m.first
  6291.       \\ <<LEFT(m.pict,250) + m.quotechar>> + ;
  6292.       m.first = .F.
  6293.    ELSE
  6294.       \        <<LEFT(m.pict,250) + m.quotechar>> + ;
  6295.    ENDIF
  6296.    m.pict = m.quotechar + SUBSTR(m.pict,251)
  6297. ENDDO
  6298.  
  6299. IF m.first
  6300.    \\ <<m.pict>>
  6301. ELSE
  6302.    \    <<m.pict>>
  6303. ENDIF
  6304. RETURN
  6305.  
  6306. *!*****************************************************************************
  6307. *!
  6308. *!      Procedure: ANYDISABLED
  6309. *!
  6310. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6311. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6312. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6313. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6314. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6315. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6316. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6317. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6318. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6319. *!
  6320. *!*****************************************************************************
  6321. PROCEDURE anydisabled
  6322. *)
  6323. *) ANYDISABLED - Place ENABLE/DISABLE clause.
  6324. *)
  6325. IF disabled
  6326.    \\ ;
  6327.    \    DISABLE
  6328. ENDIF
  6329. RETURN
  6330.  
  6331. *!*****************************************************************************
  6332. *!
  6333. *!      Procedure: ANYPICTURE
  6334. *!
  6335. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6336. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6337. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6338. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6339. *!
  6340. *!*****************************************************************************
  6341. PROCEDURE anypicture
  6342. *)
  6343. *) ANYPICTURE
  6344. *)
  6345. PRIVATE m.string, m.expr_pos, m.newstring
  6346. IF NOT EMPTY(PICTURE) AND PICTURE <> '" "'
  6347.    \\ ;
  6348.    m.string = SUBSTR(PICTURE,2)   && drop opening quotation mark
  6349.    DO CASE
  6350.    CASE SUBSTR(m.string,1,1) = m.g_itse
  6351.       \    PICTURE <<SUBSTR(m.string,2,RAT(LEFT(picture,1),m.string)-2)>>
  6352.    CASE hasexpr(m.string) > 0 && an #ITSEXPRESSION character somewhere in the middle
  6353.        m.expr_pos = hasexpr(picture)
  6354.        * Emit the first part of the PICTURE
  6355.        \    PICTURE <<LEFT(picture,expr_pos-1)>>
  6356.        * Emit a closing quotation mark, which will be the same as the opening one
  6357.        \\<<LEFT(picture,1)>>
  6358.        * Now emit the expression portion of the picture clause, not including a closing quote
  6359.        \\ + <<SUBSTR(picture,expr_pos+1,LEN(picture)-expr_pos-1))>>
  6360.    OTHERWISE
  6361.       \    PICTURE <<Picture>>
  6362.    ENDCASE
  6363. ENDIF
  6364.  
  6365.  
  6366. FUNCTION hasexpr
  6367. PARAMETER m.thepicture
  6368. RETURN ATC(m.g_itse,m.thepicture)
  6369.  
  6370. *!*****************************************************************************
  6371. *!
  6372. *!      Procedure: ANYSCROLL
  6373. *!
  6374. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6375. *!
  6376. *!*****************************************************************************
  6377. PROCEDURE anyscroll
  6378. *)
  6379. *) ANYSCROLL - Place Scroll clause if applicable.
  6380. *)
  6381. IF scrollbar
  6382.    \\ ;
  6383.    \    SCROLL
  6384. ENDIF
  6385. RETURN
  6386.  
  6387. *!*****************************************************************************
  6388. *!
  6389. *!      Procedure: ANYTAB
  6390. *!
  6391. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6392. *!
  6393. *!*****************************************************************************
  6394. PROCEDURE anytab
  6395. *)
  6396. *) ANYTAB - Place Tab clause on an @...EDIT command.
  6397. *)
  6398. IF TAB
  6399.    \\ ;
  6400.    \    TAB
  6401. ENDIF
  6402. RETURN
  6403.  
  6404. *!*****************************************************************************
  6405. *!
  6406. *!      Procedure: ANYFONT
  6407. *!
  6408. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6409. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6410. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6411. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6412. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6413. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6414. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6415. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6416. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6417. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6418. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6419. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6420. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6421. *!
  6422. *!*****************************************************************************
  6423. PROCEDURE anyfont
  6424. *)
  6425. *) ANYFONT - Place font clause on an object if in a graphical
  6426. *)        environment
  6427. *)
  6428. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6429.    \\ ;
  6430.    \    FONT "<<Fontface>>", <<Fontsize>>
  6431. ENDIF
  6432. RETURN
  6433.  
  6434. *!*****************************************************************************
  6435. *!
  6436. *!      Procedure: ANYSTYLE
  6437. *!
  6438. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6439. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6440. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6441. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6442. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6443. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6444. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6445. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6446. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6447. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6448. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6449. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6450. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6451. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  6452. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6453. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6454. *!
  6455. *!*****************************************************************************
  6456. PROCEDURE anystyle
  6457. *)
  6458. *) ANYSTYLE - Place a Style clause in an object.
  6459. *)
  6460. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6461.    IF NOT EMPTY(fontstyle) OR mode != 0 OR ;
  6462.          (NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6463.          objtype != c_ottext )
  6464.       \\ ;
  6465.       \    STYLE "
  6466.         \\<<num2style(fontstyle)>>
  6467.  
  6468.         * Is it transparent?
  6469.       IF mode = 1
  6470.          \\T
  6471.       ENDIF
  6472.  
  6473.       IF NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6474.             objtype != c_otlist AND objtype != c_ottext AND ;
  6475.                         objtype != c_otpicture
  6476.          \\<<Style>>
  6477.       ENDIF
  6478.       \\"
  6479.    ENDIF
  6480. ENDIF
  6481. RETURN
  6482.  
  6483. *!*****************************************************************************
  6484. *!
  6485. *!      Procedure: ANYPATTERN
  6486. *!
  6487. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6488. *!
  6489. *!*****************************************************************************
  6490. PROCEDURE anypattern
  6491. *)
  6492. *) ANYPATTERN - Place a PATTERN clause for boxes.
  6493. *)
  6494. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6495.    IF fillpat != 0
  6496.       \\ ;
  6497.       \    PATTERN <<Fillpat>>
  6498.    ENDIF
  6499. ENDIF
  6500. RETURN
  6501.  
  6502. *!*****************************************************************************
  6503. *!
  6504. *!      Procedure: ANYSCHEME
  6505. *!
  6506. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6507. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6508. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6509. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6510. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6511. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6512. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6513. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6514. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6515. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6516. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6517. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6518. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6519. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6520. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6521. *!
  6522. *!*****************************************************************************
  6523. PROCEDURE anyscheme
  6524. *)
  6525. *) ANYSCHEME - Place Color Scheme clause if applicable.
  6526. *)
  6527.  
  6528. IF NOT EMPTY(colorpair)
  6529.    \\ ;
  6530.    \    COLOR <<Colorpair>>
  6531.    RETURN
  6532. ENDIF
  6533. IF SCHEME <> 0
  6534.    \\ ;
  6535.    \    COLOR SCHEME <<Scheme>>
  6536.    IF objtype = c_otpopup AND scheme2<>0
  6537.       \\, <<Scheme2>>
  6538.    ENDIF
  6539. ELSE
  6540.    IF m.g_defasch2 <> 0
  6541.       DO CASE
  6542.       CASE objtype = c_ottext AND HEIGHT > 1
  6543.          \\ ;
  6544.          \    COLOR SCHEME <<m.g_defasch2>>
  6545.       CASE objtype = c_otlist
  6546.          \\ ;
  6547.          \    COLOR SCHEME <<m.g_defasch2>>
  6548.       CASE objtype = c_otpopup
  6549.          \\ ;
  6550.          \    COLOR SCHEME <<m.g_defasch1>>, <<m.g_defasch2>>
  6551.       ENDCASE
  6552.    ELSE
  6553.       IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC' ) ;
  6554.             AND ((ObjTYpe = c_otscreen AND fillred >=0) ;
  6555.              OR (ObjType <> c_otscreen AND (penred >= 0 OR fillred >= 0)) )
  6556.          m.ctrlflag = .F.   && .T. if this is a control-type object (e.g., radio button)
  6557.          \\ ;
  6558.          \    COLOR
  6559.          DO CASE
  6560.          CASE INLIST(objtype,c_otfield,c_otspinner)
  6561.             ** Field or spinner - color pair 2
  6562.             DO CASE
  6563.             CASE objcode = c_sgget OR objcode = c_sgedit
  6564.                \\ ,RGB(
  6565.             CASE objcode = c_sgsay
  6566.                \\ RGB(
  6567.             CASE objcode = c_sgfrom
  6568.                \\ ,,,,,,,,RGB(
  6569.             ENDCASE
  6570.  
  6571.          CASE objtype = c_otlist
  6572.             m.ctrlflag = .T.    && remember that this is a control object
  6573.             \\ RGB(
  6574.  
  6575.  
  6576.          CASE objtype = c_ottext OR objtype = c_otscreen OR ;
  6577.                objtype = c_otbox OR objtype = c_otline
  6578.             ** Text, Box, Line, or Screen - color pair 1
  6579.             \\ RGB(
  6580.  
  6581.          OTHERWISE
  6582.             m.ctrlflag = .T.    && remember that this is a control object
  6583.             \\ ,,,,,,,,RGB(
  6584.          ENDCASE
  6585.  
  6586.          IF penred >= 0
  6587.             \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6588.          ELSE
  6589.             \\,,,
  6590.          ENDIF
  6591.          IF fillred >= 0
  6592.             \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6593.          ELSE
  6594.             \\,,,)
  6595.          ENDIF
  6596.  
  6597.          IF m.ctrlflag AND INLIST(objtype, c_otradbut, c_otchkbox, c_otpopup,c_otlist)
  6598.             * Add one more RGB clause to control the disabled colors for control
  6599.             * objects such as radio buttons, check boxes, popups, etc.
  6600.             \\,RGB(
  6601.             IF penred >= 0
  6602.                \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6603.             ELSE
  6604.                \\,,,
  6605.             ENDIF
  6606.             IF fillred >= 0
  6607.                \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6608.             ELSE
  6609.                \\,,,)
  6610.             ENDIF
  6611.          ENDIF
  6612.       ENDIF
  6613.    ENDIF
  6614. ENDIF
  6615. RETURN
  6616.  
  6617. *!*****************************************************************************
  6618. *!
  6619. *!      Procedure: ANYPEN
  6620. *!
  6621. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6622. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6623. *!
  6624. *!*****************************************************************************
  6625. PROCEDURE anypen
  6626. *)
  6627. *) ANYPEN - Place Color Scheme clause if applicable.
  6628. *)
  6629. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6630.    \\ ;
  6631.    \    PEN <<Pensize>>, <<Penpat>>
  6632. ENDIF
  6633. RETURN
  6634.  
  6635. *!*****************************************************************************
  6636. *!
  6637. *!      Procedure: ANYVALID
  6638. *!
  6639. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6640. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6641. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6642. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6643. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6644. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6645. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6646. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6647. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6648. *!
  6649. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6650. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6651. *!
  6652. *!*****************************************************************************
  6653. PROCEDURE anyvalid
  6654. *)
  6655. *) ANYVALID - Place Valid clause if applicable.
  6656. *)
  6657. PRIVATE m.genericname, m.valid
  6658. IF NOT EMPTY(VALID)
  6659.    \\ ;
  6660.    IF validtype = 0
  6661.       m.valid = VALID
  6662.       \    VALID <<stripcr(m.valid)>>
  6663.    ELSE
  6664.       m.genericname = getcname(VALID)
  6665.       \    VALID <<m.genericname>>()
  6666.       DO addtoctrl WITH m.genericname, "VALID", VALID, name
  6667.    ENDIF
  6668. ENDIF
  6669.  
  6670. *!*****************************************************************************
  6671. *!
  6672. *!      Procedure: ANYTITLEORFOOTER
  6673. *!
  6674. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6675. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6676. *!
  6677. *!*****************************************************************************
  6678. PROCEDURE anytitleorfooter
  6679. *)
  6680. *) ANYTITLEORFOOTER - Place Window Title/Footer clause.
  6681. *)
  6682. PRIVATE m.string, m.thetag
  6683. IF NOT EMPTY(TAG)
  6684.    \\ ;
  6685.    m.string = SUBSTR(TAG,2)
  6686.    IF SUBSTR(m.string,1,1) = m.g_itse
  6687.       \    TITLE <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6688.    ELSE
  6689.       m.thetag = TAG
  6690.       \    TITLE <<m.thetag>>
  6691.    ENDIF
  6692. ENDIF
  6693. IF NOT EMPTY(tag2)
  6694.    \\ ;
  6695.    m.string = SUBSTR(tag2,2)
  6696.    IF SUBSTR(m.string,1,1) = m.g_itse
  6697.       \    FOOTER <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6698.    ELSE
  6699.       m.thetag = tag2
  6700.       \    FOOTER <<m.thetag>>
  6701.    ENDIF
  6702. ENDIF
  6703. RETURN
  6704.  
  6705.  
  6706. *!*****************************************************************************
  6707. *!
  6708. *!      Procedure: ANYWHEN
  6709. *!
  6710. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6711. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6712. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6713. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6714. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6715. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6716. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6717. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6718. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6719. *!
  6720. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6721. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6722. *!
  6723. *!*****************************************************************************
  6724. PROCEDURE anywhen
  6725. *)
  6726. *) ANYWHEN - Place a When clause in a Get field.
  6727. *)
  6728. PRIVATE m.genericname, m.when
  6729. IF EMPTY(WHEN)
  6730.    RETURN
  6731. ENDIF
  6732. \\ ;
  6733. IF whentype = 0
  6734.    m.when = WHEN
  6735.    \    WHEN <<stripcr(m.when)>>
  6736. ELSE
  6737.    m.genericname = getcname(WHEN)
  6738.    \    WHEN <<m.genericname>>()
  6739.    DO addtoctrl WITH m.genericname, "WHEN", WHEN, name
  6740. ENDIF
  6741. RETURN
  6742.  
  6743. *!*****************************************************************************
  6744. *!
  6745. *!      Procedure: ANYMESSAGE
  6746. *!
  6747. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6748. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6749. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6750. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6751. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6752. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6753. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6754. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6755. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6756. *!
  6757. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6758. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6759. *!
  6760. *!*****************************************************************************
  6761. PROCEDURE anymessage
  6762. *)
  6763. *) ANYMESSAGE - Place a message clause whenever appropriate.
  6764. *)
  6765. PRIVATE m.genericname, m.mess
  6766. IF EMPTY(MESSAGE)
  6767.    RETURN
  6768. ENDIF
  6769. \\ ;
  6770. IF messtype = 0
  6771.    m.mess = MESSAGE
  6772.    \    MESSAGE
  6773.    \\ <<stripcr(m.mess)>>
  6774. ELSE
  6775.    m.genericname = getcname(MESSAGE)
  6776.    \    MESSAGE <<m.genericname>>()
  6777.    DO addtoctrl WITH m.genericname, "MESSAGE", MESSAGE, name
  6778. ENDIF
  6779. RETURN
  6780.  
  6781. *!*****************************************************************************
  6782. *!
  6783. *!      Procedure: ANYERROR
  6784. *!
  6785. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6786. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6787. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6788. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6789. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6790. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6791. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6792. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6793. *!
  6794. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6795. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6796. *!
  6797. *!*****************************************************************************
  6798. PROCEDURE anyerror
  6799. *)
  6800. *) ANYERROR - Place an error clause whenever appropriate.
  6801. *)
  6802. PRIVATE m.genericname, m.err
  6803. IF EMPTY(ERROR)
  6804.    RETURN
  6805. ENDIF
  6806. \\ ;
  6807. IF errortype = 0
  6808.    m.err = ERROR
  6809.    \    ERROR
  6810.    \\ <<stripcr(m.err)>>
  6811. ELSE
  6812.    m.genericname = getcname(ERROR)
  6813.    \    ERROR <<m.genericname>>()
  6814.    DO addtoctrl WITH m.genericname, "ERROR", ERROR, name
  6815. ENDIF
  6816. RETURN
  6817.  
  6818. *!*****************************************************************************
  6819. *!
  6820. *!      Procedure: ANYFILL
  6821. *!
  6822. *!*****************************************************************************
  6823. PROCEDURE anyfill
  6824. *)
  6825. *) ANYFILL - Place the Fill clause whenever appropriate.
  6826. *)
  6827. IF fillchar <> c_null
  6828.    \\ ;
  6829.    \    FILL "<<Fillchar>>"
  6830. ENDIF
  6831. RETURN
  6832.  
  6833. *!*****************************************************************************
  6834. *!
  6835. *!      Procedure: ANYWINDOWCHARS
  6836. *!
  6837. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6838. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6839. *!
  6840. *!*****************************************************************************
  6841. PROCEDURE anywindowchars
  6842. *)
  6843. *) ANYWINDOWCHARS - Place window characteristics options.
  6844. *)
  6845. *) Description:
  6846. *) Place the FLOAT, GROW, CLOSE, ZOOM, SHADOW, and MINIMIZE clauses
  6847. *) for a window painted by the user.
  6848. *)
  6849. \\ ;
  6850. \    <<IIF(Float, "FLOAT ;", "NOFLOAT ;")>>
  6851. \    <<IIF(Close, "CLOSE", "NOCLOSE")>>
  6852. IF SHADOW
  6853.    \\ ;
  6854.    \    SHADOW
  6855. ENDIF
  6856. IF m.g_genvers <> "MAC"
  6857.     IF MINIMIZE
  6858.        \\ ;
  6859.        \    MINIMIZE
  6860.     ELSE
  6861.        \\ ;
  6862.        \    NOMINIMIZE
  6863.     ENDIF
  6864. ENDIF
  6865. RETURN
  6866.  
  6867. *!*****************************************************************************
  6868. *!
  6869. *!      Procedure: ANYBORDER
  6870. *!
  6871. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6872. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6873. *!
  6874. *!*****************************************************************************
  6875. PROCEDURE anyborder
  6876. *)
  6877. *) ANYBORDER - Place Border type clause on a box.
  6878. *)
  6879. *) Description:
  6880. *) Place border type clause on a box depending on the setting of
  6881. *) the field Border.
  6882. *)
  6883. IF BORDER<>1
  6884.    \\ ;
  6885. ENDIF
  6886.  
  6887. DO CASE
  6888. CASE BORDER = 0
  6889.    \    NONE
  6890. CASE BORDER = 2
  6891.    \    DOUBLE
  6892. CASE BORDER = 3
  6893.    \    PANEL
  6894. CASE BORDER = 4
  6895.    \    SYSTEM
  6896. ENDCASE
  6897. RETURN
  6898.  
  6899. *!*****************************************************************************
  6900. *!
  6901. *!      Procedure: ANYWALLPAPER
  6902. *!
  6903. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6904. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6905. *!
  6906. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6907. *!
  6908. *!*****************************************************************************
  6909. PROCEDURE anywallpaper
  6910. *)
  6911. *) ANYWALLPAPER - Place FILL FILE clause on any window.
  6912. *)
  6913. IF !EMPTY(PICTURE) 
  6914.    m.relpath = findrelpath(SUBSTR(PICTURE, 2, LEN(PICTURE) - 2))
  6915.     IF !EMPTY(basename(m.relpath))
  6916.       \\ ;
  6917.       \    FILL FILE LOCFILE("<<m.relpath>>",<<bitmapstr(c_all)>>, ;
  6918.       \        "Where is <<LOWER(basename(m.relpath))>>?")
  6919.    ENDIF
  6920. ENDIF
  6921. RETURN
  6922.  
  6923. *!*****************************************************************************
  6924. *!
  6925. *!      Procedure: ANYICON
  6926. *!
  6927. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6928. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6929. *!
  6930. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6931. *!
  6932. *!*****************************************************************************
  6933. PROCEDURE anyicon
  6934. *)
  6935. *) ANYICON - Place ICON FILE clause on any window.
  6936. *)
  6937. IF !EMPTY(ORDER) AND ORDER <> '""'
  6938.    m.relpath = findrelpath(SUBSTR(ORDER, 2, LEN(ORDER) - 2))
  6939.     IF !EMPTY(basename(m.relpath))
  6940.       \\ ;
  6941.       \    ICON FILE LOCFILE("<<m.relpath>>","<<iconstr()>>", ;
  6942.       \        "Where is <<LOWER(basename(m.relpath))>>?")
  6943.    ENDIF
  6944. ENDIF
  6945. RETURN
  6946.  
  6947. *!*****************************************************************************
  6948. *!
  6949. *!      Procedure: WINDOWFROMTO
  6950. *!
  6951. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6952. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  6953. *!
  6954. *!*****************************************************************************
  6955. PROCEDURE windowfromto
  6956. *)
  6957. *) WINDOWFROMTO - Place FROM...TO clause on any window.
  6958. *)
  6959. *) Description:
  6960. *) Place FROM...TO clause on any window designed in the screen
  6961. *) painter.  If window is to be centered, then adjust the coordinates
  6962. *) accordingly.
  6963. *)
  6964. PARAMETER m.xcoord, m.ycoord
  6965. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6966.    SET DECIMALS TO 3
  6967. ENDIF
  6968. IF PARAMETERS() = 0
  6969.    IF CENTER
  6970.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6971.          \    AT  <<Vpos>>, <<Hpos>>  ;
  6972.          \    SIZE <<Height>>,<<Width>>
  6973.       ELSE
  6974.          \    FROM INT((SROW()-<<Height>>)/2),
  6975.          \\INT((SCOL()-<<Width>>)/2) ;
  6976.          \    TO INT((SROW()-<<Height>>)/2)+<<Height-1>>,
  6977.          \\INT((SCOL()-<<Width>>)/2)+<<Width-1>>
  6978.       ENDIF
  6979.    ELSE
  6980.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6981.          \    AT <<Vpos>>, <<Hpos>> ;
  6982.          \    SIZE <<Height>>,<<Width>>
  6983.       ELSE
  6984.          \    FROM <<Vpos>>, <<Hpos>> ;
  6985.          \    TO <<Height+Vpos-1>>,<<Width+Hpos-1>>
  6986.       ENDIF
  6987.    ENDIF
  6988. ELSE
  6989.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6990.       \    AT <<m.xcoord>>, <<m.ycoord>> ;
  6991.       \    SIZE <<Height>>,<<Width>>
  6992.    ELSE
  6993.       \    FROM <<m.xcoord>>, <<m.ycoord>> ;
  6994.       \    TO <<Height+m.xcoord-1>>,<<Width+m.ycoord-1>>
  6995.    ENDIF
  6996. ENDIF
  6997. SET DECIMALS TO 0
  6998. RETURN
  6999.  
  7000. **
  7001. ** Code Generating Documentation in Control and Format files.
  7002. **
  7003.  
  7004. *!*****************************************************************************
  7005. *!
  7006. *!      Procedure: HEADER
  7007. *!
  7008. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  7009. *!
  7010. *!*****************************************************************************
  7011. PROCEDURE HEADER
  7012. *)
  7013. *) HEADER - Generate application program's header.
  7014. *)
  7015. *) Description:
  7016. *) As a part of the application's header generate program name, name
  7017. *) of the author of the program, copyright notice, company name and
  7018. *) address, and the word 'Description:' which will be followed with
  7019. *) the application description generated by a separate procedure.
  7020. *)
  7021. IF LEN(_PRETEXT) <> 0
  7022.    \
  7023. ENDIF
  7024. \\*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7025. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7026. \*       <<m.g_verti1>> <<DATE()>>
  7027. \\<<PADC(UPPER(ALLTRIM(strippath(m.g_outfile))),IIF(SET("CENTURY")="ON",35,37))," ")>>
  7028. \\  <<TIME()>> <<m.g_verti2>>
  7029. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7030. \*       <<m.g_corn5>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn6>>
  7031. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7032. \*       <<m.g_verti1>> <<m.g_devauthor>>
  7033. \\<<SAFEREPL(" ",56-LEN(m.g_devauthor))>><<m.g_verti2>>
  7034. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7035. \*       <<m.g_verti1>>
  7036. \\ Copyright (c) <<YEAR(DATE())>>
  7037. IF LEN(ALLTRIM(m.g_devcompany)) <= 36
  7038.    \\ <<ALLTRIM(m.g_devcompany)>>
  7039.    \\<<SAFEREPL(" ",37-LEN(ALLTRIM(m.g_devcompany)))>>
  7040.    \\<<m.g_verti2>>
  7041. ELSE
  7042.    \\ <<SAFEREPL(" ",37)>><<m.g_verti2>>
  7043.    \*       <<m.g_verti1>> <<m.g_devcompany>>
  7044.    \\<<SAFEREPL(" ",56-LEN(m.g_devcompany))>><<m.g_verti2>>
  7045. ENDIF
  7046. \*       <<m.g_verti1>> <<m.g_devaddress>>
  7047. \\<<SAFEREPL(" ",56-LEN(m.g_devaddress))>><<m.g_verti2>>
  7048.  
  7049. \*       <<m.g_verti1>> <<ALLTRIM(m.g_devcity)>>, <<m.g_devstate>>
  7050. \\  <<ALLTRIM(m.g_devzip)>>
  7051. \\<<SAFEREPL(" ",50-(LEN(ALLTRIM(m.g_devcity)+ALLTRIM(m.g_devzip))))>>
  7052. \\<<m.g_verti2>>
  7053.  
  7054. IF !INLIST(ALLTRIM(UPPER(m.g_devctry)),"USA","COUNTRY") AND !EMPTY(m.g_devctry)
  7055.    \*       <<m.g_verti1>> <<ALLTRIM(m.g_devctry)>>
  7056.    \\<<SAFEREPL(" ",50-(LEN(ALLTRIM(m.g_devctry))))>>
  7057.    \\<<m.g_verti2>>
  7058. ENDIF
  7059.  
  7060. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7061. \*       <<m.g_verti1>> Description:
  7062. \\                                            <<m.g_verti2>>
  7063. \*       <<m.g_verti1>>
  7064. \\ This program was automatically generated by GENSCRN.
  7065. \\    <<m.g_verti2>>
  7066. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7067. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7068. \
  7069. RETURN
  7070.  
  7071. *!*****************************************************************************
  7072. *!
  7073. *!      Procedure: GENFUNCHEADER
  7074. *!
  7075. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  7076. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  7077. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7078. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7079. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7080. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  7081. *!
  7082. *!*****************************************************************************
  7083. PROCEDURE genfuncheader
  7084. *)
  7085. *) GENFUNCHEADER - Generate Comment for Function/Procedure.
  7086. *)
  7087. PARAMETER m.procname, m.from, m.readlevel, m.varname
  7088. m.g_snippcnt = m.g_snippcnt + 1
  7089. \
  7090. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7091. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7092. IF m.readlevel
  7093.    \*       <<m.g_verti1>>
  7094.    \\ <<UPPER(m.procname)>>           <<m.from>>
  7095.    \\<<SAFEREPL(" ",45-LEN(m.procname+m.from))>><<m.g_verti2>>
  7096. ELSE
  7097.    \*       <<m.g_verti1>>
  7098.    \\ <<UPPER(m.procname)>>           <<m.varname>> <<m.from>>
  7099.    \\<<SAFEREPL(" ",44-LEN(m.procname+m.varname+m.from))>><<m.g_verti2>>
  7100. ENDIF
  7101. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7102. \*       <<m.g_verti1>> Function Origin:
  7103. \\<<SAFEREPL(" ",40)>><<m.g_verti2>>
  7104. IF m.readlevel
  7105.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7106.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7107.    \*       <<m.g_verti1>> From Platform:
  7108.    \\       <<VersionCap(m.g_genvers, .F.)>>
  7109.    \\<<SAFEREPL(" ",35-LEN(VersionCap(m.g_genvers, .F.)))>>
  7110.    \\<<m.g_verti2>>
  7111.    \*       <<m.g_verti1>> From Screen:
  7112.    IF m.g_nscreens > 1 AND NOT m.g_multread
  7113.       \\         Multiple Screens
  7114.       \\<<SAFEREPL(" ",19)>><<m.g_verti2>>
  7115.    ELSE
  7116.       \\         <<basename(SYS(2014,DBF()))>>
  7117.       \\<<SAFEREPL(" ",35-LEN(basename(SYS(2014,DBF()))))>>
  7118.       \\<<m.g_verti2>>
  7119.    ENDIF
  7120.    \*       <<m.g_verti1>> Called By:           READ Statement
  7121.    \\<<SAFEREPL(" ",21)>><<m.g_verti2>>
  7122.    \*       <<m.g_verti1>> Snippet Number:
  7123.    \\      <<ALLTRIM(STR(m.g_snippcnt,2))>>
  7124.    \\<<SAFEREPL(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,2))))>><<m.g_verti2>>
  7125.    \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7126.    \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7127.    \*
  7128.    RETURN
  7129. ENDIF
  7130. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7131. \*       <<m.g_verti1>> From Platform:
  7132. \\       <<VersionCap(m.g_genvers, .F.)>>
  7133. \\<<SAFEREPL(" ",35-LEN(VersionCap(m.g_genvers, .F.)))>>
  7134. \\<<m.g_verti2>>
  7135. \*       <<m.g_verti1>> From Screen:
  7136. \\         <<basename(SYS(2014,DBF()))>>
  7137. \\,     Record Number:  <<STR(RECNO(),3)>>
  7138. \\<<SAFEREPL(" ",10-LEN(basename(SYS(2014,DBF())+STR(RECNO(),3))))>>
  7139. \\<<m.g_verti2>>
  7140. IF NOT EMPTY(m.varname)
  7141.    \*       <<m.g_verti1>> Variable:            <<m.varname>>
  7142.    \\<<SAFEREPL(" ",35-LEN(m.varname))>><<m.g_verti2>>
  7143. ENDIF
  7144. \*       <<m.g_verti1>> Called By:           <<m.from+" Clause">>
  7145. \\<<SAFEREPL(" ",35-LEN(m.from+" Clause"))>><<m.g_verti2>>
  7146. IF OBJECT(objtype) <> ""
  7147.    \*       <<m.g_verti1>> Object Type:
  7148.    \\         <<Object(Objtype)>>
  7149.    \\<<SAFEREPL(" ",35-LEN(Object(Objtype)))>><<m.g_verti2>>
  7150. ENDIF
  7151. \*       <<m.g_verti1>> Snippet Number:
  7152. \\      <<ALLTRIM(STR(m.g_snippcnt,3))>>
  7153. \\<<SAFEREPL(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,3))))>><<m.g_verti2>>
  7154. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7155. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7156. \*
  7157. RETURN
  7158.  
  7159. *!*****************************************************************************
  7160. *!
  7161. *!      Procedure: COMMENTBLOCK
  7162. *!
  7163. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  7164. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  7165. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  7166. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  7167. *!               : GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  7168. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  7169. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  7170. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  7171. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  7172. *!
  7173. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7174. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  7175. *!
  7176. *!*****************************************************************************
  7177. PROCEDURE commentblock
  7178. *)
  7179. *) COMMENTBLOCK - Generate a comment block.
  7180. *)
  7181. PARAMETER m.dbalias, m.string
  7182. PRIVATE m.msg
  7183. IF !EMPTY(basename(m.dbalias))
  7184.    m.msg = basename(m.dbalias)+"/"+versioncap(m.g_genvers, .F.)+m.string
  7185. ELSE
  7186.    m.msg = versioncap(m.g_genvers, .F.)+m.string
  7187. ENDIF
  7188. \
  7189. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7190. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7191. \*       <<m.g_verti1>>
  7192. \\ <<PADC(m.msg,55," ")>>
  7193. \\ <<m.g_verti2>>
  7194. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7195. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7196. \*
  7197. \
  7198.  
  7199. *!*****************************************************************************
  7200. *!
  7201. *!      Procedure: PROCCOMMENTBLOCK
  7202. *!
  7203. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  7204. *!
  7205. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7206. *!
  7207. *!*****************************************************************************
  7208. PROCEDURE proccommentblock
  7209. *)
  7210. *) PROCCOMMENTBLOCK - Generate a procedure comment block.
  7211. *)
  7212. PARAMETER m.dbalias, m.string
  7213. PRIVATE m.msg
  7214. m.msg = basename(m.dbalias)+m.string
  7215. \
  7216. \*       <<m.g_corn1>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn2>>
  7217. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7218. \*       <<m.g_verti1>>
  7219. \\ <<PADC(m.msg,55," ")>>
  7220. \\ <<m.g_verti2>>
  7221. \*       <<m.g_verti1>><<SAFEREPL(" ",57)>><<m.g_verti2>>
  7222. \*       <<m.g_corn3>><<SAFEREPL(m.g_horiz,57)>><<m.g_corn4>>
  7223. \*
  7224. \
  7225. RETURN
  7226.  
  7227. *!*****************************************************************************
  7228. *!
  7229. *!      Procedure: GENCOMMENT
  7230. *!
  7231. *!      Called by: GENVALIDBODY       (procedure in GENSCRN.PRG)
  7232. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7233. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7234. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7235. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7236. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  7237. *!
  7238. *!*****************************************************************************
  7239. PROCEDURE gencomment
  7240. *)
  7241. *) GENCOMMENT - Generate a comment.
  7242. *)
  7243. PARAMETER m.msg
  7244. \*
  7245. \* <<m.msg>>
  7246. \*
  7247.  
  7248. *!*****************************************************************************
  7249. *!
  7250. *!      Procedure: SAFEREPL
  7251. *!
  7252. *!*****************************************************************************
  7253. FUNCTION saferepl
  7254. * REPLICATE shell
  7255. PARAMETER m.strg, m.num
  7256. RETURN REPLICATE(m.strg, max(m.num, 0))
  7257.  
  7258. **
  7259. ** General Supporting Routines
  7260. **
  7261.  
  7262. *!*****************************************************************************
  7263. *!
  7264. *!       Function: BASENAME
  7265. *!
  7266. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  7267. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  7268. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7269. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7270. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7271. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7272. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  7273. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  7274. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  7275. *!
  7276. *!          Calls: STRIPPATH()        (function  in GENSCRN.PRG)
  7277. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  7278. *!
  7279. *!*****************************************************************************
  7280. FUNCTION basename
  7281. PARAMETER m.filename
  7282. RETURN strippath(stripext(m.filename))
  7283.  
  7284. *!*****************************************************************************
  7285. *!
  7286. *!       Function: STRIPEXT
  7287. *!
  7288. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  7289. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7290. *!
  7291. *!*****************************************************************************
  7292. FUNCTION stripext
  7293. *)
  7294. *) STRIPEXT - Strip the extension from a file name.
  7295. *)
  7296. *) Description:
  7297. *) Use the algorithm employed by FoxPRO itself to strip a
  7298. *) file of an extension (if any): Find the rightmost dot in
  7299. *) the filename.  If this dot occurs to the right of a "\"
  7300. *) or ":", then treat everything from the dot rightward
  7301. *) as an extension.  Of course, if we found no dot,
  7302. *) we just hand back the filename unchanged.
  7303. *)
  7304. *) Parameters:
  7305. *) filename - character string representing a file name
  7306. *)
  7307. *) Return value:
  7308. *) The string "filename" with any extension removed
  7309. *)
  7310. PARAMETER m.filename
  7311. PRIVATE m.dotpos, m.terminator
  7312. m.dotpos = RAT(".", m.filename)
  7313. m.terminator = MAX(RAT("\", m.filename), RAT(":", m.filename))
  7314. IF m.dotpos > m.terminator
  7315.    m.filename = LEFT(m.filename, m.dotpos-1)
  7316. ENDIF
  7317. RETURN m.filename
  7318.  
  7319. *!*****************************************************************************
  7320. *!
  7321. *!       Function: STRIPPATH
  7322. *!
  7323. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  7324. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7325. *!
  7326. *!*****************************************************************************
  7327. FUNCTION strippath
  7328. *)
  7329. *) STRIPPATH - Strip the path from a file name.
  7330. *)
  7331. *) Description:
  7332. *) Find positions of backslash in the name of the file.  If there is one
  7333. *) take everything to the right of its position and make it the new file
  7334. *) name.  If there is no slash look for colon.  Again if found, take
  7335. *) everything to the right of it as the new name.  If neither slash
  7336. *) nor colon are found then return the name unchanged.
  7337. *)
  7338. *) Parameters:
  7339. *) filename - character string representing a file name
  7340. *)
  7341. *) Return value:
  7342. *) The string "filename" with any path removed
  7343. *)
  7344. PARAMETER m.filename
  7345. PRIVATE m.slashpos, m.namelen, m.colonpos
  7346. m.slashpos = RAT("\", m.filename)
  7347. IF m.slashpos > 0
  7348.    m.namelen  = LEN(m.filename) - m.slashpos
  7349.    m.filename = RIGHT(m.filename, m.namelen)
  7350. ELSE
  7351.    m.colonpos = RAT(":", m.filename)
  7352.    IF m.colonpos > 0
  7353.       m.namelen  = LEN(m.filename) - m.colonpos
  7354.       m.filename = RIGHT(m.filename, m.namelen)
  7355.    ENDIF
  7356. ENDIF
  7357. RETURN m.filename
  7358.  
  7359. *!*****************************************************************************
  7360. *!
  7361. *!       Function: STRIPCR
  7362. *!
  7363. *!*****************************************************************************
  7364. FUNCTION stripcr
  7365. *)
  7366. *) STRIPCR - Strip off terminating carriage returns and line feeds
  7367. *)
  7368. PARAMETER m.strg
  7369. * Don't use a CHRTRAN since it's remotely possible that the CR or LF might
  7370. * be in a user's quoted string.
  7371. strg = ALLTRIM(strg)
  7372. i = LEN(strg)
  7373. DO WHILE i >= 0 AND INLIST(SUBSTR(strg,i,1),CHR(13),CHR(10))
  7374.    i = i - 1
  7375. ENDDO
  7376. RETURN LEFT(strg,i)
  7377.  
  7378. *!*****************************************************************************
  7379. *!
  7380. *!       Function: ADDBS
  7381. *!
  7382. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7383. *!
  7384. *!*****************************************************************************
  7385. FUNCTION addbs
  7386. *)
  7387. *) ADDBS - Add a backslash unless there is one already there.
  7388. *)
  7389. PARAMETER m.pathname
  7390. PRIVATE ALL
  7391. m.separator = IIF(_MAC,":","\")
  7392. m.pathname = ALLTRIM(UPPER(m.pathname))
  7393. IF !(RIGHT(m.pathname,1) $ '\:') AND !EMPTY(m.pathname)
  7394.    m.pathname = m.pathname + m.separator
  7395. ENDIF
  7396. RETURN m.pathname
  7397.  
  7398. *!*****************************************************************************
  7399. *!
  7400. *!       Function: JUSTFNAME
  7401. *!
  7402. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7403. *!
  7404. *!*****************************************************************************
  7405. FUNCTION justfname
  7406. *)
  7407. *) JUSTFNAME - Return just the filename (i.e., no path) from "filname"
  7408. *)
  7409. PARAMETERS m.filname
  7410. PRIVATE ALL
  7411. IF RAT('\',m.filname) > 0
  7412.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  7413. ENDIF
  7414. IF AT(':',m.filname) > 0
  7415.    m.filname = SUBSTR(m.filname,AT(':',m.filname)+1,255)
  7416. ENDIF
  7417. RETURN ALLTRIM(UPPER(m.filname))
  7418.  
  7419. *!*****************************************************************************
  7420. *!
  7421. *!       Function: JUSTPATH
  7422. *!
  7423. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7424. *!
  7425. *!*****************************************************************************
  7426. FUNCTION justpath
  7427. *)
  7428. *) JUSTPATH - Returns just the pathname.
  7429. *)
  7430. PARAMETERS m.filname
  7431. PRIVATE ALL
  7432. m.filname = ALLTRIM(UPPER(m.filname))
  7433. IF '\' $ m.filname
  7434.    m.filname = SUBSTR(m.filname,1,RAT('\',m.filname))
  7435.    IF RIGHT(m.filname,1) = '\' AND LEN(m.filname) > 1 ;
  7436.             AND SUBSTR(m.filname,LEN(m.filname)-1,1) <> ':'
  7437.          filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
  7438.    ENDIF
  7439.    RETURN m.filname
  7440. ELSE
  7441.    RETURN ''
  7442. ENDIF
  7443.  
  7444.  
  7445. *!*****************************************************************************
  7446. *!
  7447. *!       Function: JUSTEXT
  7448. *!
  7449. *!*****************************************************************************
  7450. FUNCTION justext
  7451. * Return just the extension from "filname"
  7452. PARAMETERS m.filname
  7453. PRIVATE ALL
  7454. filname = justfname(m.filname)   && prevents problems with ..\ paths
  7455. m.ext = ""
  7456. IF AT('.',m.filname) > 0
  7457.    m.ext = SUBSTR(m.filname,AT('.',m.filname)+1,3)
  7458. ENDIF
  7459. RETURN UPPER(m.ext)
  7460.  
  7461. *!*****************************************************************************
  7462. *!
  7463. *!       Function: FORCEEXT
  7464. *!
  7465. *!          Calls: JUSTPATH()         (function  in GENSCRN.PRG)
  7466. *!               : JUSTFNAME()        (function  in GENSCRN.PRG)
  7467. *!               : ADDBS()            (function  in GENSCRN.PRG)
  7468. *!
  7469. *!*****************************************************************************
  7470. FUNCTION forceext
  7471. *)
  7472. *) FORCEEXT - Force filename to have a particular extension.
  7473. *)
  7474. PARAMETERS m.filname,m.ext
  7475. PRIVATE ALL
  7476. IF SUBSTR(m.ext,1,1) = "."
  7477.    m.ext = SUBSTR(m.ext,2,3)
  7478. ENDIF
  7479.  
  7480. m.pname = justpath(m.filname)
  7481. m.filname = justfname(UPPER(ALLTRIM(m.filname)))
  7482. IF AT('.',m.filname) > 0
  7483.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1) + '.' + m.ext
  7484. ELSE
  7485.    m.filname = m.filname + '.' + m.ext
  7486. ENDIF
  7487. RETURN addbs(m.pname) + m.filname
  7488.  
  7489. *!*****************************************************************************
  7490. *!
  7491. *!       Function: UNIQUEWIN
  7492. *!
  7493. *!      Called by: GENWINDEFI         (procedure in GENSCRN.PRG)
  7494. *!
  7495. *!*****************************************************************************
  7496. FUNCTION uniquewin
  7497. *)
  7498. *) UNIQUEWIN - Check if a window name is unique.
  7499. *)
  7500. PARAMETER m.windowname, m.windcnt, m.arry
  7501. EXTERNAL ARRAY arry
  7502. PRIVATE m.found, m.i, m.first, m.middle
  7503. m.found  = .F.
  7504. m.first  = 1
  7505. m.last   = m.windcnt
  7506. m.middle = 0
  7507.  
  7508. IF EMPTY(arry[1,1])
  7509.    RETURN 1
  7510. ENDIF
  7511. DO WHILE (m.last >= m.first) AND NOT m.found
  7512.    m.middle = INT((m.first+m.last) / 2)
  7513.    DO CASE
  7514.    CASE m.windowname < arry[m.middle,1]
  7515.       m.last = m.middle - 1
  7516.    CASE m.windowname > arry[m.middle,1]
  7517.       m.first = m.middle + 1
  7518.    OTHERWISE
  7519.       m.found = .T.
  7520.    ENDCASE
  7521. ENDDO
  7522. IF m.found
  7523.    RETURN 0
  7524. ELSE
  7525.    RETURN m.first
  7526. ENDIF
  7527. RETURN 
  7528.  
  7529. *!*****************************************************************************
  7530. *!
  7531. *!      Procedure: ADDTOCTRL
  7532. *!
  7533. *!      Called by: ELEMRANGE          (procedure in GENSCRN.PRG)
  7534. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  7535. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  7536. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  7537. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  7538. *!
  7539. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  7540. *!               : GENFUNCHEADER      (procedure in GENSCRN.PRG)
  7541. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  7542. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  7543. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  7544. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  7545. *!
  7546. *!*****************************************************************************
  7547. PROCEDURE addtoctrl
  7548. *)
  7549. *) ADDTOCTRL - Generate clause code for object level cluses.
  7550. *)
  7551. PARAMETER m.procname, m.from, m.memo, m.varname
  7552. PRIVATE m.linecnt, m.count, m.textline, m.genfunction, m.notcomnt, m.at, ;
  7553.    m.thispretext, m.in_dec, m.platnum, m.wnamelen, m.upline, m.thisplat
  7554.  
  7555. m.thisplat = IIF(TYPE("platform") <> "U",platform,"DOS")
  7556. m.platnum = getplatnum(m.thisplat)
  7557.  
  7558. * Write this clause to the temporary file
  7559. _TEXT = m.g_tmphandle
  7560. m.thispretext = _PRETEXT
  7561. _PRETEXT = ""
  7562.  
  7563. m.genfunction = .F.
  7564. m.notcomnt = 0
  7565. m.linecnt = MEMLINES(m.memo)
  7566. _MLINE = 0
  7567. DO genfuncheader WITH m.procname, m.from, .F., ALLTRIM(m.varname)
  7568. FOR m.count = 1 TO m.linecnt
  7569.    m.textline = MLINE(m.memo, 1, _MLINE)
  7570.    DO killcr WITH m.textline
  7571.    m.upline = UPPER(LTRIM(CHRTRAN(m.textline,chr(9),' ')))
  7572.    IF oktogenerate(@upline, @notcomnt)
  7573.       IF m.notcomnt > 0 AND NOT m.genfunction
  7574.          \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7575.          in_dec = SET("DECIMALS")
  7576.          SET DECIMALS TO 0
  7577.          \#REGION <<INT(m.g_screen)>>
  7578.          SET DECIMALS TO in_dec
  7579.          m.genfunction = .T.
  7580.       ENDIF
  7581.  
  7582.       IF NOT EMPTY(g_wnames[m.g_screen, m.platnum])
  7583.          m.at = atwname(g_wnames[m.g_screen, m.platnum], m.textline)
  7584.          IF m.at <> 0 AND !iscomment(@textline)
  7585.             m.wnamelen = LEN(g_wnames[m.g_screen, m.platnum])
  7586.             \<<STUFF(m.textline, m.at, m.wnamelen,g_screens[m.g_screen,2])>>
  7587.          ELSE
  7588.             IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7589.                \<<m.textline>>
  7590.             ENDIF
  7591.          ENDIF
  7592.       ELSE
  7593.          IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7594.             \<<m.textline>>
  7595.          ENDIF
  7596.       ENDIF
  7597.    ENDIF
  7598. ENDFOR
  7599. IF m.notcomnt = 0
  7600.    \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7601. ENDIF
  7602. _TEXT = m.g_orghandle
  7603. _PRETEXT = m.thispretext
  7604. RETURN 
  7605.  
  7606. *!*****************************************************************************
  7607. *!
  7608. *!       Function: OKTOGENERATE
  7609. *!
  7610. *!      Called by: ADDTOCTRL          (procedure in GENSCRN.PRG)
  7611. *!
  7612. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  7613. *!               : MATCH()            (function  in GENSCRN.PRG)
  7614. *!
  7615. *!*****************************************************************************
  7616. FUNCTION oktogenerate
  7617. *)
  7618. *) OKTOGENERATE - Ok to generate this line?
  7619. *)
  7620. *) Description:
  7621. *) Check if the code segment provided by the user for the object level
  7622. *) VALID, MESSAGE, and WHEN clauses does not contain 'FUNCTION',
  7623. *) 'PROCEDURE' or 'PARAMETER' statements as its first non-comment
  7624. *) statements.  Further, do not output #NAME directives. This is done on line by
  7625. *) line basis.
  7626. *)
  7627. *) "notcomnt" needs to be passed by reference, and is changed in this module
  7628. *) m.statement must already be in upper case and trimmed.  It may be passed by reference.
  7629. PARAMETER m.statement, m.notcomnt
  7630.  
  7631. PRIVATE m.asterisk, m.ampersand, m.isnote, m.name, m.word1
  7632. IF EMPTY(m.statement)
  7633.    RETURN .T.
  7634. ENDIF
  7635.  
  7636. DO CASE
  7637. CASE AT("*", m.statement) = 1 ;
  7638.       OR AT(m.g_dblampersand, m.statement) = 1 ;
  7639.       OR AT("NOTE", m.statement) = 1
  7640.    RETURN .T.
  7641. OTHERWISE
  7642.    * OK, it's not a comment
  7643.    m.notcomnt = m.notcomnt + 1
  7644.    * Make a quick test to see if we may exclude this line
  7645.    IF AT(LEFT(statement,1),"PF#") > 0
  7646.       * Postpone the expensive wordnum and match functions as long as possible
  7647.       word1 = CHRTRAN(wordnum(statement,1),';','')
  7648.       DO CASE
  7649.       CASE match(word1,"PROCEDURE") OR match(word1,"FUNCTION") OR match(word1,"PARAMETERS")
  7650.          *
  7651.          * If the first non-comment line is a FUNCTION, PROCEDURE, or
  7652.          * a PARAMETER statement then do not generate it.
  7653.          *
  7654.          IF m.notcomnt = 1
  7655.             RETURN .F.
  7656.          ENDIF
  7657.       CASE LEFT(statement,5) == "#NAME"   && Don't ever emit a #NAME directive
  7658.          RETURN .F.
  7659.       ENDCASE
  7660.    ENDIF
  7661. ENDCASE
  7662. RETURN .T.
  7663.  
  7664. *!*****************************************************************************
  7665. *!
  7666. *!       Function: OBJECT
  7667. *!
  7668. *!*****************************************************************************
  7669. FUNCTION OBJECT
  7670. *)
  7671. *) OBJECT - Return name of an object.
  7672. *)
  7673. PARAMETER m.objecttype
  7674. PRIVATE m.objname
  7675. DO CASE
  7676. CASE m.objecttype = 11
  7677.    m.objname = "List"
  7678. CASE m.objecttype = 12
  7679.    m.objname = "Push Button"
  7680. CASE m.objecttype = 13
  7681.    m.objname = "Radio Button"
  7682. CASE m.objecttype = 14
  7683.    m.objname = "Check Box"
  7684. CASE m.objecttype = 15
  7685.    m.objname = "Field"
  7686. CASE m.objecttype = 16
  7687.    m.objname = "Popup"
  7688. OTHERWISE
  7689.    m.objname = ""
  7690. ENDCASE
  7691. RETURN m.objname
  7692.  
  7693. *!*****************************************************************************
  7694. *!
  7695. *!      Procedure: COMBINE
  7696. *!
  7697. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7698. *!
  7699. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7700. *!
  7701. *!*****************************************************************************
  7702. PROCEDURE combine
  7703. *)
  7704. *) COMBINE - Combine the original and the temp files.
  7705. *)
  7706. PRIVATE m.size, m.top, m.end, m.status, m.chunk
  7707.  
  7708. IF m.g_graphic
  7709.    SET MESSAGE TO 'Merging Files'
  7710. ENDIF
  7711. m.size = FSEEK(m.g_tmphandle,0,2)
  7712. m.top  = FSEEK(m.g_tmphandle,0)
  7713.  
  7714. DO WHILE .T.
  7715.    m.chunk = IIF(m.size>65000, 65000, m.size)
  7716.    m.end   = FSEEK(m.g_orghandle,0,2)
  7717.    m.status = FWRITE(m.g_orghandle,FREAD(m.g_tmphandle,m.chunk))
  7718.    IF m.status = 0 AND m.size > 0
  7719.       DO errorhandler WITH "Unsuccessful file merge...",;
  7720.          LINENO(), c_error_2
  7721.    ENDIF
  7722.    m.size = m.size - 65000
  7723.    IF m.size < 0
  7724.       EXIT
  7725.    ENDIF
  7726. ENDDO
  7727. IF m.g_graphic
  7728.    SET MESSAGE TO 'Generation Complete'
  7729. ELSE
  7730.    WAIT CLEAR
  7731. ENDIF
  7732. RETURN
  7733.  
  7734. **
  7735. ** Code Associated With Displaying of the Thermometer
  7736. **
  7737.  
  7738. *!*****************************************************************************
  7739. *!
  7740. *!      Procedure: ACTTHERM
  7741. *!
  7742. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7743. *!
  7744. *!*****************************************************************************
  7745. PROCEDURE acttherm
  7746. *)
  7747. *) ACTTHERM(<text>) - Activate thermometer.
  7748. *)
  7749. *) Activates thermometer.  Update the thermometer with UPDTHERM().
  7750. *) Thermometer window is named "thermometer."  Be sure to RELEASE
  7751. *) this window when done with thermometer.  Creates the global
  7752. *) m.g_thermwidth.
  7753. *)
  7754. PARAMETER m.text
  7755. PRIVATE m.prompt
  7756.  
  7757. IF m.g_graphic
  7758.    m.prompt = LOWER(m.g_outfile)
  7759.     m.prompt = thermfname(m.prompt)
  7760.  
  7761.    DO CASE
  7762.    CASE _WINDOWS
  7763.       DEFINE WINDOW thermomete ;
  7764.          AT  INT((SROW() - (( 5.615 * ;
  7765.          FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7766.          FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
  7767.          INT((SCOL() - (( 63.833 * ;
  7768.          FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7769.          FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
  7770.          SIZE 5.615,63.833 ;
  7771.          FONT m.g_dlgface, m.g_dlgsize ;
  7772.          STYLE m.g_dlgstyle ;
  7773.          NOFLOAT ;
  7774.          NOCLOSE ;
  7775.          NONE ;
  7776.          COLOR RGB(0, 0, 0, 192, 192, 192)
  7777.       MOVE WINDOW thermomete CENTER
  7778.       ACTIVATE WINDOW thermomete NOSHOW
  7779.  
  7780.       @ 0.5,3 SAY m.text FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle
  7781.       @ 1.5,3 SAY m.prompt FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle
  7782.       @ 0.000,0.000 TO 0.000,63.833 ;
  7783.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7784.       @ 0.000,0.000 TO 5.615,0.000 ;
  7785.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7786.       @ 0.385,0.667 TO 5.231,0.667 ;
  7787.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7788.       @ 0.308,0.667 TO 0.308,63.167 ;
  7789.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7790.       @ 0.385,63.000 TO 5.308,63.000 ;
  7791.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7792.       @ 5.231,0.667 TO 5.231,63.167 ;
  7793.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7794.       @ 5.538,0.000 TO 5.538,63.833 ;
  7795.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7796.       @ 0.000,63.667 TO 5.615,63.667 ;
  7797.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7798.       @ 3.000,3.333 TO 4.231,3.333 ;
  7799.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7800.       @ 3.000,60.333 TO 4.308,60.333 ;
  7801.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7802.       @ 3.000,3.333 TO 3.000,60.333 ;
  7803.          COLOR RGB(128, 128, 128, 128, 128, 128)
  7804.       @ 4.231,3.333 TO 4.231,60.333 ;
  7805.          COLOR RGB(255, 255, 255, 255, 255, 255)
  7806.       m.g_thermwidth = 56.269
  7807.    CASE _MAC
  7808.       DEFINE WINDOW thermomete ;
  7809.          AT  INT((SROW() - (( 5.62 * ;
  7810.          FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7811.          FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
  7812.          INT((SCOL() - (( 63.83 * ;
  7813.          FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  7814.          FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
  7815.          SIZE 5.62,63.83 ;
  7816.          FONT m.g_dlgface, m.g_dlgsize ;
  7817.          STYLE m.g_dlgstyle ;
  7818.          NOFLOAT ;
  7819.          NOCLOSE ;
  7820.             NONE ;
  7821.          COLOR RGB(0, 0, 0, 192, 192, 192)
  7822.       MOVE WINDOW thermomete CENTER
  7823.       ACTIVATE WINDOW thermomete NOSHOW
  7824.  
  7825.       IF ISCOLOR()
  7826.          @ 0.000,0.000 TO 5.62,63.83 PATTERN 1;
  7827.              COLOR RGB(192, 192, 192, 192, 192, 192)
  7828.           @ 0.000,0.000 TO 0.000,63.83 ;
  7829.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7830.           @ 0.000,0.000 TO 5.62,0.000 ;
  7831.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7832.           @ 0.385,0.67 TO 5.23,0.67 ;
  7833.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7834.           @ 0.31,0.67 TO 0.31,63.17 ;
  7835.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7836.           @ 0.385,63.000 TO 5.31,63.000 ;
  7837.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7838.           @ 5.23,0.67 TO 5.23,63.17 ;
  7839.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7840.           @ 5.54,0.000 TO 5.54,63.83 ;
  7841.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7842.           @ 0.000,63.67 TO 5.62,63.67 ;
  7843.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7844.           @ 3.000,3.33 TO 4.23,3.33 ;
  7845.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7846.           @ 3.000,60.33 TO 4.31,60.33 ;
  7847.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7848.           @ 3.000,3.33 TO 3.000,60.33 ;
  7849.              COLOR RGB(128, 128, 128, 128, 128, 128)
  7850.           @ 4.23,3.33 TO 4.23,60.33 ;
  7851.              COLOR RGB(255, 255, 255, 255, 255, 255)
  7852.       ELSE
  7853.          @ 0.000, 0.000 TO 5.62, 63.830  PEN 2
  7854.           @ 0.230, 0.500 TO 5.39, 63.333  PEN 1
  7855.        ENDIF
  7856.       @ 0.5,3 SAY m.text FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle+"T" ;
  7857.          COLOR RGB(0,0,0,192,192,192)
  7858.       @ 1.5,3 SAY m.prompt FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle+"T" ;
  7859.          COLOR RGB(0,0,0,192,192,192)
  7860.  
  7861.       m.g_thermwidth = 56.27
  7862.         IF !ISCOLOR()
  7863.             @ 3.000,3.33 TO 4.23,m.g_thermwidth + 3.33 
  7864.         ENDIF
  7865.    ENDCASE
  7866.    SHOW WINDOW thermomete TOP
  7867. ELSE
  7868.    m.prompt = SUBSTR(SYS(2014,m.g_outfile),1,48)+;
  7869.       IIF(LEN(m.g_outfile)>48,"...","")
  7870.  
  7871.    DEFINE WINDOW thermomete;
  7872.       FROM INT((SROW()-6)/2), INT((SCOL()-57)/2) ;
  7873.       TO INT((SROW()-6)/2) + 6, INT((SCOL()-57)/2) + 57;
  7874.       DOUBLE COLOR SCHEME 5
  7875.    ACTIVATE WINDOW thermomete NOSHOW
  7876.  
  7877.    m.g_thermwidth = 50
  7878.    @ 0,3 SAY m.text
  7879.    @ 1,3 SAY UPPER(m.prompt)
  7880.    @ 2,1 TO 4,m.g_thermwidth+4 &g_boxstrg
  7881.  
  7882.    SHOW WINDOW thermomete TOP
  7883. ENDIF
  7884. RETURN
  7885.  
  7886. *!*****************************************************************************
  7887. *!
  7888. *!      Procedure: UPDTHERM
  7889. *!
  7890. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7891. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  7892. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  7893. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  7894. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  7895. *!
  7896. *!*****************************************************************************
  7897. PROCEDURE updtherm
  7898. *)
  7899. *) UPDTHERM(<percent>) - Update thermometer.
  7900. *)
  7901. PARAMETER m.percent
  7902. PRIVATE m.nblocks, m.percent
  7903.  
  7904. ACTIVATE WINDOW thermomete
  7905.  
  7906. * Map to the number of platforms we are generating for
  7907. m.percent = MIN(INT(m.percent / m.g_numplatforms) ,100)
  7908.  
  7909. m.nblocks = (m.percent/100) * (m.g_thermwidth)
  7910. DO CASE
  7911. CASE _WINDOWS
  7912.    @ 3.000,3.333 TO 4.231,m.nblocks + 3.333 ;
  7913.       PATTERN 1 COLOR RGB(128, 128, 128, 128, 128, 128)
  7914. CASE _MAC
  7915.    *@ 3.000,3.33 TO 4.23,m.nblocks + 3.33 ;
  7916.    *   PATTERN 1 COLOR RGB(0, 0, 0, 220, 140, 120)
  7917.    @ 3.000,3.33 TO 4.23,m.nblocks + 3.33 ;
  7918.       PATTERN 1 COLOR RGB(0, 0, 128, 0, 0, 128)
  7919. OTHERWISE
  7920.    @ 3,3 SAY REPLICATE("€",m.nblocks)
  7921. ENDCASE
  7922. RETURN
  7923.  
  7924. *!*****************************************************************************
  7925. *!
  7926. *!      Procedure: DEACTTHERMO
  7927. *!
  7928. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7929. *!
  7930. *!*****************************************************************************
  7931. PROCEDURE deactthermo
  7932. *)
  7933. *) DEACTTHERMO - Deactivate and Release thermometer window.
  7934. *)
  7935. IF WEXIST("thermomete")
  7936.    RELEASE WINDOW thermomete
  7937. ENDIF
  7938. RETURN
  7939.  
  7940. *!*****************************************************************************
  7941. *!
  7942. *!      Procedure: THERMADJ
  7943. *!
  7944. *!*****************************************************************************
  7945. FUNCTION thermadj
  7946. * Map the local thermometer from local (this platform) to global (all platforms)
  7947. * When all platforms have been accounted for, we want to show m.finish percent.
  7948. PARAMETERS m.pnum, m.current, m.finish
  7949. =assert(m.current <= m.finish,"Thermometer error!  Current > finish.")
  7950. =assert(BETWEEN(m.finish,0,100),"Thermometer error! Finish out of range.")
  7951. RETURN (m.finish * (m.pnum - 1)) + m.current
  7952.  
  7953.  
  7954. *!*****************************************************************************
  7955. *!
  7956. *!      Procedure: THERMFNAME
  7957. *!
  7958. *!*****************************************************************************
  7959. FUNCTION thermfname
  7960. PARAMETER m.fname
  7961. PRIVATE m.addelipse, m.g_pathsep, m.g_thermfface, m.g_thermfsize, m.g_thermfstyle
  7962.  
  7963. #define c_space 50
  7964. IF _MAC
  7965.     m.g_thermfface = "Geneva"
  7966.     m.g_thermfsize = 10
  7967.     m.g_thermfstyle = "B"
  7968. ELSE
  7969.     m.g_thermfface = "MS Sans Serif"
  7970.     m.g_thermfsize = 8
  7971.     m.g_thermfstyle = "B"
  7972. ENDIF
  7973.  
  7974. * Translate the filename into Mac native format
  7975. IF _MAC
  7976.     m.g_pathsep = ":"
  7977.     m.fname = SYS(2027, m.fname)
  7978. ELSE
  7979.     m.g_pathsep = "\"    
  7980. ENDIF
  7981.  
  7982. IF TXTWIDTH(m.fname,m.g_thermfface,m.g_thermfsize,m.g_thermfstyle) > c_space
  7983.     * Make it fit in c_space
  7984.     m.fname = partialfname(m.fname, c_space - 1)
  7985.     m.addelipse = .F.
  7986.     DO WHILE TXTWIDTH(m.fname+'...',m.g_thermfface,m.g_thermfsize,m.g_thermfstyle) > c_space
  7987.         m.fname = LEFT(m.fname, LEN(m.fname) - 1)
  7988.         m.addelipse = .T.
  7989.     ENDDO
  7990.     IF m.addelipse
  7991.         m.fname = m.fname + "..."
  7992.    ENDIF
  7993. ENDIF
  7994. RETURN m.fname
  7995.  
  7996.  
  7997.  
  7998. *!*****************************************************************************
  7999. *!
  8000. *!      Procedure: PARTIALFNAME
  8001. *!
  8002. *!*****************************************************************************
  8003. FUNCTION partialfname    
  8004. PARAMETER m.filname, m.fillen
  8005. * Return a filname no longer than m.fillen characters.  Take some chars
  8006. * out of the middle if necessary.  No matter what m.fillen is, this function
  8007. * always returns at least the file stem and extension.
  8008. PRIVATE m.bname, m.elipse, m.remain
  8009. m.elipse = "..." + m.g_pathsep
  8010. IF _MAC
  8011.     m.bname = SUBSTR(m.filname, RAT(":",m.filname)+1)
  8012. ELSE
  8013.     m.bname = justfname(m.filname)
  8014. ENDIF
  8015. DO CASE
  8016. CASE LEN(m.filname) <= m.fillen 
  8017.    m.retstr = m.filname
  8018. CASE LEN(m.bname) + LEN(m.elipse) >= m.fillen
  8019.    m.retstr = m.bname
  8020. OTHERWISE
  8021.    m.remain = MAX(m.fillen - LEN(m.bname) - LEN(m.elipse), 0)
  8022.    IF _MAC
  8023.        m.retstr = LEFT(SUBSTR(m.filname,1,RAT(":",m.filname)-1),m.remain) ;
  8024.             +m.elipse+m.bname
  8025.    ELSE
  8026.          m.retstr = LEFT(justpath(m.filname),m.remain)+m.elipse+m.bname
  8027.    ENDIF
  8028. ENDCASE
  8029. RETURN m.retstr
  8030.  
  8031. **
  8032. ** Error Handling Code
  8033. **
  8034.  
  8035. *!*****************************************************************************
  8036. *!
  8037. *!      Procedure: ERRORHANDLER
  8038. *!
  8039. *!      Called by: GENSCRN.PRG
  8040. *!               : OPENPROJDBF()      (function  in GENSCRN.PRG)
  8041. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  8042. *!               : CHECKPARAM()       (function  in GENSCRN.PRG)
  8043. *!               : PREPFILE           (procedure in GENSCRN.PRG)
  8044. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  8045. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  8046. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  8047. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8048. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8049. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  8050. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  8051. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  8052. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  8053. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  8054. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  8055. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  8056. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  8057. *!               : COMBINE            (procedure in GENSCRN.PRG)
  8058. *!
  8059. *!          Calls: CLEANUP            (procedure in GENSCRN.PRG)
  8060. *!               : ERRLOG             (procedure in GENSCRN.PRG)
  8061. *!               : ERRSHOW            (procedure in GENSCRN.PRG)
  8062. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  8063. *!
  8064. *!*****************************************************************************
  8065. PROCEDURE errorhandler
  8066. *)
  8067. *) ERRORHANDLER - Error Processing Center.
  8068. *)
  8069. PARAMETERS m.msg, m.linenum, m.errcode
  8070. IF ERROR() = 22   && too many memory variables--just bomb out as fast as we can
  8071.    ON ERROR
  8072.    DO cleanup
  8073.    CANCEL
  8074. ENDIF
  8075.  
  8076. DO CASE
  8077. CASE errcode == "Minor"
  8078.    DO errlog WITH m.msg, m.linenum
  8079.    m.g_status = 1
  8080. CASE errcode == "Serious"
  8081.    DO errlog  WITH m.msg, m.linenum
  8082.    DO errshow WITH m.msg, m.linenum
  8083.    m.g_status = 2
  8084.    ON ERROR
  8085. CASE errcode == "Fatal"
  8086.    ON ERROR
  8087.    IF m.g_havehand = .T.
  8088.       DO errlog WITH m.msg, m.linenum
  8089.       DO closefile WITH m.g_orghandle
  8090.       DO closefile WITH m.g_tmphandle
  8091.    ENDIF
  8092.    DO errshow WITH m.msg, m.linenum
  8093.    IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8094.       RELEASE WINDOW thermometer
  8095.    ENDIF
  8096.    DO cleanup
  8097.    CANCEL
  8098. ENDCASE
  8099. RETURN 
  8100.  
  8101. *!*****************************************************************************
  8102. *!
  8103. *!      Procedure: ESCHANDLER
  8104. *!
  8105. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  8106. *!
  8107. *!          Calls: BUILDDISABLE       (procedure in GENSCRN.PRG)
  8108. *!               : CLEANUP            (procedure in GENSCRN.PRG)
  8109. *!
  8110. *!*****************************************************************************
  8111. PROCEDURE eschandler
  8112. *)
  8113. *) ESCHANDLER - Escape handler.
  8114. *)
  8115. ON ERROR
  8116. WAIT WINDOW "Generation process stopped." NOWAIT
  8117. DO builddisable
  8118. IF m.g_havehand
  8119.    ERASE (m.g_outfile)
  8120.    ERASE (m.g_tmpfile)
  8121. ENDIF
  8122. IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8123.    RELEASE WINDOW thermometer
  8124. ENDIF
  8125. DO cleanup
  8126. CANCEL
  8127.  
  8128. *!*****************************************************************************
  8129. *!
  8130. *!      Procedure: ERRLOG
  8131. *!
  8132. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  8133. *!
  8134. *!          Calls: OPENERRFILE        (procedure in GENSCRN.PRG)
  8135. *!
  8136. *!*****************************************************************************
  8137. PROCEDURE errlog
  8138. *)
  8139. *) ERRLOG - Save an error message in the error log file.
  8140. *)
  8141. PARAMETER m.msg, m.linenum
  8142. DO openerrfile
  8143.  
  8144. SET CONSOLE OFF
  8145. \\GENERATOR: <<ALLTRIM(m.msg)>>
  8146. IF NOT EMPTY(m.linenum)
  8147.    \\ LINE NUMBER: <<m.linenum>>
  8148. ENDIF
  8149. \
  8150. = FCLOSE(_TEXT)
  8151. _TEXT = m.g_orghandle
  8152. RETURN 
  8153.  
  8154. *!*****************************************************************************
  8155. *!
  8156. *!      Procedure: ERRSHOW
  8157. *!
  8158. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  8159. *!               : OPENERRFILE        (procedure in GENSCRN.PRG)
  8160. *!
  8161. *!*****************************************************************************
  8162. PROCEDURE errshow
  8163. *)
  8164. *) ERRSHOW - Show error in an alert box on the screen.
  8165. *)
  8166. PARAMETER m.msg, m.lineno
  8167. PRIVATE m.curcursor
  8168.  
  8169. IF m.g_graphic
  8170.     IF _MAC
  8171.        DEFINE WINDOW ALERT ;
  8172.           AT  INT((SROW() - (( 6.615 * ;
  8173.           FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8174.           FONTMETRIC(1, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2), ;
  8175.           INT((SCOL() - (( 63.833 * ;
  8176.           FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8177.           FONTMETRIC(6, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2) ;
  8178.           SIZE 6.615,63.833 ;
  8179.           FONT m.g_dlgface, m.g_dlgsize ;
  8180.           STYLE m.g_dlgstyle ;
  8181.           NOCLOSE ;
  8182.           DOUBLE ;
  8183.           TITLE "Genscrn Error" ;
  8184.           COLOR RGB(0, 0, 0, 255, 255, 255)
  8185.     ELSE
  8186.        DEFINE WINDOW ALERT ;
  8187.           AT  INT((SROW() - (( 6.615 * ;
  8188.           FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8189.           FONTMETRIC(1, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2), ;
  8190.           INT((SCOL() - (( 63.833 * ;
  8191.           FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
  8192.           FONTMETRIC(6, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2) ;
  8193.           SIZE 6.615,63.833 ;
  8194.           FONT m.g_dlgface, m.g_dlgsize ;
  8195.           STYLE m.g_dlgstyle ;
  8196.           NOCLOSE ;
  8197.           DOUBLE ;
  8198.           TITLE "Genscrn Error" ;
  8199.           COLOR RGB(0, 0, 0, 255, 255, 255)
  8200.    ENDIF
  8201.    MOVE WINDOW ALERT CENTER
  8202.    ACTIVATE WINDOW ALERT NOSHOW
  8203.  
  8204.    m.dispmsg = m.msg
  8205.    IF TXTWIDTH(m.dispmsg) > WCOLS()
  8206.       * Make sure it isn't too long.
  8207.       DO WHILE TXTWIDTH(m.dispmsg+'...') > WCOLS()
  8208.          m.dispmsg = LEFT(m.dispmsg,LEN(m.dispmsg)-1)
  8209.       ENDDO
  8210.       IF m.msg <> m.dispmsg    && Has display message been shortened?
  8211.          m.dispmsg = m.dispmsg + '...'
  8212.       ENDIF
  8213.    ENDIF
  8214.  
  8215.    @ 1,MAX((WCOLS()-TXTWIDTH( m.dispmsg ))/2,1) SAY m.dispmsg
  8216.  
  8217.    m.msg = "Genscrn Line Number: "+STR(m.lineno, 4)
  8218.    @ 2,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  8219.  
  8220.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  8221.       m.msg = "Generating from: "+LOWER(g_screens[m.g_screen,1])
  8222.       @ 3,MAX((WCOLS()-TXTWIDTH( m.msg ))/2,1) SAY m.msg
  8223.    ENDIF
  8224.  
  8225.    m.msg = "Press any key to cleanup and exit..."
  8226.    @ 4,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  8227.  
  8228.    SHOW WINDOW ALERT
  8229. ELSE
  8230.    DEFINE WINDOW ALERT;
  8231.       FROM INT((SROW()-7)/2), INT((SCOL()-50)/2) TO INT((SROW()-7)/2) + 6, INT((SCOL()-50)/2) + 50 ;
  8232.       FLOAT NOGROW NOCLOSE NOZOOM SHADOW DOUBLE;
  8233.       COLOR SCHEME 7
  8234.  
  8235.    ACTIVATE WINDOW ALERT
  8236.  
  8237.    @ 0,0 CLEAR
  8238.    @ 1,0 SAY PADC(SUBSTR(m.msg,1,44)+;
  8239.       IIF(LEN(m.msg)>44,"...",""), WCOLS())
  8240.    @ 2,0 SAY PADC("Line Number: "+STR(m.lineno, 4), WCOLS())
  8241.  
  8242.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  8243.       m.msg = "Working on screen: "+LOWER(g_screens[m.g_screen])
  8244.       @ 3,0 SAY PADC(m.msg,WCOLS())
  8245.    ENDIF
  8246.  
  8247.    @ 4,0 SAY PADC("Press any key to cleanup and exit...", WCOLS())
  8248. ENDIF
  8249.  
  8250. m.curcursor = SET( "CURSOR" )
  8251. SET CURSOR OFF
  8252.  
  8253. WAIT ""
  8254.  
  8255. RELEASE WINDOW ALERT
  8256. SET CURSOR &curcursor
  8257.  
  8258. RELEASE WINDOW ALERT
  8259. RETURN 
  8260.  
  8261. *!*****************************************************************************
  8262. *!
  8263. *!      Procedure: OPENERRFILE
  8264. *!
  8265. *!      Called by: ERRLOG             (procedure in GENSCRN.PRG)
  8266. *!
  8267. *!          Calls: ERRSHOW            (procedure in GENSCRN.PRG)
  8268. *!
  8269. *!*****************************************************************************
  8270. PROCEDURE openerrfile
  8271. *)
  8272. *) OPENERRFILE - Open error file.
  8273. *)
  8274. PRIVATE m.errfile, m.errhandle
  8275. m.errfile   = m.g_errlog+".ERR"
  8276. m.errhandle = FOPEN(m.errfile,2)
  8277. IF m.errhandle < 0
  8278.    m.errhandle = FCREATE(m.errfile)
  8279.    IF m.errhandle < 0
  8280.       DO errshow WITH ".ERR could not be opened...", LINENO()
  8281.       m.g_status = 2
  8282.       IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8283.          RELEASE WINDOW thermometer
  8284.       ENDIF
  8285.       ON ERROR
  8286.       RETURN TO MASTER
  8287.    ENDIF
  8288. ELSE
  8289.    = FSEEK(m.errhandle,0,2)
  8290. ENDIF
  8291. IF SET("TEXTMERGE") = "OFF"
  8292.    SET TEXTMERGE ON
  8293. ENDIF
  8294. _TEXT = m.errhandle
  8295.  
  8296. *!*****************************************************************************
  8297. *!
  8298. *!      Procedure: PUSHINDENT
  8299. *!
  8300. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8301. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8302. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8303. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8304. *!
  8305. *!*****************************************************************************
  8306. PROCEDURE pushindent
  8307. *)
  8308. *) PUSHINDENT - Add another indentation level
  8309. *)
  8310. _PRETEXT = CHR(9) + _PRETEXT
  8311. RETURN 
  8312.  
  8313. *!*****************************************************************************
  8314. *!
  8315. *!      Procedure: POPINDENT
  8316. *!
  8317. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8318. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8319. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8320. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8321. *!
  8322. *!*****************************************************************************
  8323. PROCEDURE popindent
  8324. *)
  8325. *) POPINDENT - Remove one indentation level
  8326. *)
  8327. IF LEFT(_PRETEXT,1) = CHR(9)
  8328.    _PRETEXT = SUBSTR(_PRETEXT,2)
  8329. ENDIF
  8330. RETURN 
  8331.  
  8332. *!*****************************************************************************
  8333. *!
  8334. *!      Procedure: COUNTPLATFORMS
  8335. *!
  8336. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8337. *!
  8338. *!*****************************************************************************
  8339. FUNCTION countplatforms
  8340. *)
  8341. *) COUNTPLATFORMS - Count the number of platforms in this SCX that are in common across
  8342. *)                    all the SCXs in this screen set.
  8343. *)
  8344. PRIVATE m.cnt, m.i
  8345. IF TYPE("g_platforms") <> "U"
  8346.    m.cnt = 0
  8347.    FOR m.i = 1 TO ALEN(g_platforms)
  8348.       IF !EMPTY(g_platforms[m.i])
  8349.          m.cnt = m.cnt + 1
  8350.       ENDIF
  8351.    ENDFOR
  8352.    RETURN m.cnt
  8353. ENDIF
  8354. RETURN 0
  8355.  
  8356. *!*****************************************************************************
  8357. *!
  8358. *!      Function: LOOKUPPLATFORM
  8359. *!
  8360. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8361. *!
  8362. *!*****************************************************************************
  8363. FUNCTION lookupplatform
  8364. *)
  8365. *) LOOKUPPLATFORM - Return the n-th platform name
  8366. *)
  8367. PARAMETER m.n
  8368. IF TYPE("g_platforms") <> "U" AND ALEN(g_platforms) >= m.n ;
  8369.       AND m.n > 0 AND TYPE("g_platforms[m.n]") = "C"
  8370.    RETURN UPPER(g_platforms[m.n])
  8371. ENDIF
  8372. RETURN ""
  8373.  
  8374. *!*****************************************************************************
  8375. *!
  8376. *!      Function: HASRECORDS
  8377. *!
  8378. *!*****************************************************************************
  8379. FUNCTION hasrecords
  8380. *)
  8381. *) HASRECORDS - Return .T. if plat records are in the screen.
  8382. *)
  8383. PARAMETER m.plat
  8384. IF TYPE("g_platforms") = "U"
  8385.    RETURN IIF(m.plat = "DOS",.T.,.F.)
  8386. ELSE
  8387.    RETURN IIF(ASCAN(g_platforms,m.plat) > 0,.T.,.F.)
  8388. ENDIF
  8389. RETURN 
  8390.  
  8391. *!*****************************************************************************
  8392. *!
  8393. *!       Function: GETPARAM
  8394. *!
  8395. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  8396. *!
  8397. *!          Calls: ISCOMMENT()        (function  in GENSCRN.PRG)
  8398. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  8399. *!               : MATCH()            (function  in GENSCRN.PRG)
  8400. *!
  8401. *!*****************************************************************************
  8402. FUNCTION getparam
  8403. *)
  8404. *) GETPARAM - Return the PARAMETER statement from a setup snippet, if one is there
  8405. *)
  8406. PARAMETER m.snipname
  8407. PRIVATE m.i, m.thisparam, m.numlines, m.thisline, m.word1, m.contin
  8408.  
  8409. * Do a quick check to see if we need to search further.
  8410. IF ATC("PARA",&snipname) = 0
  8411.    RETURN ""
  8412. ENDIF
  8413.  
  8414. m.numlines = MEMLINES(&snipname)
  8415. _MLINE = 0
  8416. m.i = 1
  8417. DO WHILE m.i <= m.numlines
  8418.    m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8419.    DO killcr WITH m.thisline
  8420.    
  8421.    * Drop any double-ampersand comment
  8422.    IF AT(m.g_dblampersand,m.thisline) > 0
  8423.       m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8424.    ENDIF
  8425.    
  8426.    IF !EMPTY(m.thisline) AND !iscomment(@thisline)
  8427.       * See if the first non-blank, non-comment, non-directive, non-EXTERNAL
  8428.       * line is a #SECTION 1
  8429.       DO CASE
  8430.       CASE LEFT(m.thisline,5) = "#SECT" AND AT('1',m.thisline) <> 0
  8431.          * Read until we find a #SECTION 2, the end of the snippet or a
  8432.          * PARAMETER statement.
  8433.          DO WHILE m.i <= m.numlines
  8434.             m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8435.             DO killcr WITH m.thisline
  8436.             
  8437.             * Drop any double-ampersand comment
  8438.             IF AT(m.g_dblampersand,m.thisline) > 0
  8439.                m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8440.             ENDIF
  8441.             
  8442.             m.word1 = wordnum(CHRTRAN(m.thisline,CHR(9)+';',' '),1)
  8443.             DO CASE
  8444.             CASE match(m.word1,"PARAMETERS")
  8445.             
  8446.                * Replace tabs with spaces
  8447.                m.thisline = LTRIM(CHRTRAN(m.thisline,CHR(9)," "))
  8448.  
  8449.                * Process continuation lines.  Replace tabs in incoming lines with spaces.
  8450.                DO WHILE RIGHT(RTRIM(m.thisline),1) = ';'
  8451.                   m.thisline = m.thisline + ' '+ CHR(13)+CHR(10)+CHR(9)
  8452.                   m.contin = MLINE(&snipname, 1, _MLINE)
  8453.                   DO killcr WITH m.contin
  8454.                   m.contin = CHRTRAN(LTRIM(m.contin),CHR(9)," ")
  8455.                   m.thisline = m.thisline + UPPER(m.contin)
  8456.                ENDDO
  8457.                
  8458.                * Clean up the parameters so that minor differences in
  8459.                * spacing don't cause the comparisons to fail.
  8460.  
  8461.                * Take the parameters but not the PARAMETER keyword itself
  8462.                m.thisparam = SUBSTR(m.thisline,AT(' ',m.thisline)+1)
  8463.                DO WHILE INLIST(LEFT(m.thisparam,1),CHR(10),CHR(13),CHR(9),' ')
  8464.                   m.thisparam = SUBSTR(m.thisparam,2)
  8465.                ENDDO
  8466.  
  8467.                * Force single spacing in the param string
  8468.                DO WHILE AT('  ',m.thisparam) > 0
  8469.                   m.thisparam = STRTRAN(m.thisparam,'  ',' ')
  8470.                ENDDO
  8471.  
  8472.                * Drop "m." designations so that they don't make the variables look different
  8473.                m.thisparam = STRTRAN(m.thisparam,'m.','')
  8474.                m.thisparam = STRTRAN(m.thisparam,'m->','')
  8475.                
  8476.                RETURN LOWER(m.thisparam)
  8477.             CASE LEFT(m.thisline,5) = "#SECT" AND AT('2',m.thisline) <> 0
  8478.                * No parameter statement, since we found #SECTION 2 first
  8479.                RETURN ""
  8480.             ENDCASE
  8481.             m.i = m.i + 1
  8482.          ENDDO
  8483.       CASE LEFT(m.thisline,1) = "#"   && some other directive
  8484.          * Do nothing.  Get next line.
  8485.       CASE match(wordnum(m.thisline,1),"EXTERNAL")
  8486.          * Ignore it.  This doesn't disqualify a later statement from being a PARAMETER
  8487.          * statement.
  8488.       OTHERWISE
  8489.          * no #SECTION 1, so no parameters
  8490.          RETURN ""
  8491.       ENDCASE
  8492.    ENDIF
  8493.    m.i = m.i + 1
  8494. ENDDO
  8495. RETURN ""
  8496.  
  8497.  
  8498. *!*****************************************************************************
  8499. *!
  8500. *!       Function: MATCH
  8501. *!
  8502. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8503. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8504. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8505. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8506. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8507. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8508. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8509. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8510. *!
  8511. *!*****************************************************************************
  8512. FUNCTION match
  8513. *)
  8514. *) MATCH - Returns TRUE is candidate is a valid 4-or-more-character abbreviation of keyword
  8515. *)
  8516. PARAMETER m.candidate, m.keyword
  8517. PRIVATE m.in_exact, m.retlog
  8518.  
  8519. m.in_exact = SET("EXACT")
  8520. SET EXACT OFF
  8521. DO CASE
  8522. CASE EMPTY(m.candidate)
  8523.    m.retlog = EMPTY(m.keyword)
  8524. CASE LEN(m.candidate) < 4
  8525.    m.retlog = IIF(m.candidate == m.keyword,.T.,.F.)
  8526. OTHERWISE
  8527.    m.retlog = IIF(m.keyword = m.candidate,.T.,.F.)
  8528. ENDCASE
  8529. IF m.in_exact != "OFF"
  8530.    SET EXACT ON
  8531. ENDIF
  8532.  
  8533. RETURN m.retlog
  8534.  
  8535. *!*****************************************************************************
  8536. *!
  8537. *!       Function: WORDNUM
  8538. *!
  8539. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8540. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8541. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8542. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8543. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8544. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  8545. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8546. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8547. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8548. *!
  8549. *!*****************************************************************************
  8550. FUNCTION wordnum
  8551. *)
  8552. *) WORDNUM - Returns w_num-th word from string strg
  8553. *)
  8554. PARAMETERS m.strg,m.w_num
  8555. PRIVATE strg,s1,w_num,ret_str
  8556.  
  8557. m.s1 = ALLTRIM(m.strg)
  8558.  
  8559. * Replace tabs with spaces
  8560. m.s1 = CHRTRAN(m.s1,CHR(9)," ")
  8561.  
  8562. * Reduce multiple spaces to a single space
  8563. DO WHILE AT('  ',m.s1) > 0
  8564.    m.s1 = STRTRAN(m.s1,'  ',' ')
  8565. ENDDO
  8566.  
  8567. ret_str = ""
  8568. DO CASE
  8569. CASE m.w_num > 1
  8570.    DO CASE
  8571.    CASE AT(" ",m.s1,m.w_num-1) = 0   && No word w_num.  Past end of string.
  8572.       m.ret_str = ""
  8573.    CASE AT(" ",m.s1,m.w_num) = 0     && Word w_num is last word in string.
  8574.       m.ret_str = SUBSTR(m.s1,AT(" ",m.s1,m.w_num-1)+1,255)
  8575.    OTHERWISE                         && Word w_num is in the middle.
  8576.       m.strt_pos = AT(" ",m.s1,m.w_num-1)
  8577.       m.ret_str  = SUBSTR(m.s1,strt_pos,AT(" ",m.s1,m.w_num)+1 - strt_pos)
  8578.    ENDCASE
  8579. CASE m.w_num = 1
  8580.    IF AT(" ",m.s1) > 0               && Get first word.
  8581.       m.ret_str = SUBSTR(m.s1,1,AT(" ",m.s1)-1)
  8582.    ELSE                              && There is only one word.  Get it.
  8583.       m.ret_str = m.s1
  8584.    ENDIF
  8585. ENDCASE
  8586. RETURN ALLTRIM(m.ret_str)
  8587.  
  8588.  
  8589. *!*****************************************************************************
  8590. *!
  8591. *!       Function: GETCNAME
  8592. *!
  8593. *!      Called by: SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  8594. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  8595. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  8596. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  8597. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  8598. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  8599. *!
  8600. *!*****************************************************************************
  8601. FUNCTION getcname
  8602. *) GETCNAME - Generates a name for a clause.  Will take name from a
  8603. *)              generator directive stored in a snippet if present,
  8604. *)              or generates a generic name otherwise.  The name is
  8605. *)              designated by a #NAME name directive
  8606. *)
  8607. PARAMETERS m.snippet
  8608. PRIVATE dirname
  8609. IF ATC("#NAME",m.snippet) > 0
  8610.    m.dirname = MLINE(m.snippet, ATCLINE('#NAME',m.snippet))
  8611.    DO killcr WITH m.dirname
  8612.    m.dirname = UPPER(ALLTRIM(SUBSTR(m.dirname,AT(' ',m.dirname)+1)))
  8613.    IF !EMPTY(m.dirname)
  8614.       RETURN m.dirname
  8615.    ENDIF
  8616. ENDIF
  8617. RETURN LOWER(SYS(2015))
  8618.  
  8619. *!*****************************************************************************
  8620. *!
  8621. *!      Procedure: NOTEAREA
  8622. *!
  8623. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  8624. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  8625. *!
  8626. *!*****************************************************************************
  8627. PROCEDURE notearea
  8628. *)
  8629. *) NOTEAREA - Note that we are using this area so that we can clean up at exit
  8630. *)
  8631. g_areas[m.g_areacount] = SELECT()
  8632. m.g_areacount = m.g_areacount + 1
  8633. RETURN
  8634.  
  8635. *!*****************************************************************************
  8636. *!
  8637. *!      Procedure: CLEARAREAS
  8638. *!
  8639. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8640. *!
  8641. *!*****************************************************************************
  8642. PROCEDURE clearareas
  8643. *)
  8644. *) CLEARAREAS - Clear the ones we opened.
  8645. *)
  8646. FOR i = 1 TO m.g_areacount
  8647.    SELECT g_areas[m.i]
  8648.    USE
  8649. ENDFOR
  8650. RETURN
  8651.  
  8652. *!*****************************************************************************
  8653. *!
  8654. *!      Procedure: INITTICK
  8655. *!
  8656. *!      Called by: GENSCRN.PRG
  8657. *!
  8658. *!*****************************************************************************
  8659. PROCEDURE inittick
  8660. *)
  8661. *) INITTICK, TICK, and TOCK - Profiling functions
  8662. *)
  8663. IF TYPE("ticktock") = "U"
  8664.    PUBLIC ticktock[10]
  8665. ENDIF
  8666. ticktock = 0
  8667. RETURN 
  8668.  
  8669. *!*****************************************************************************
  8670. *!
  8671. *!       Function: TICK
  8672. *!
  8673. *!      Called by: GENSCRN.PRG
  8674. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8675. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8676. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8677. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8678. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8679. *!
  8680. *!*****************************************************************************
  8681. FUNCTION tick
  8682. *)
  8683. *) INITTICK, TICK, and TOCK - Profiling functions
  8684. *)
  8685. PARAMETER m.bucket
  8686. ticktock[bucket] = ticktock[bucket] - SECONDS()
  8687. RETURN 
  8688.  
  8689. *!*****************************************************************************
  8690. *!
  8691. *!       Function: TOCK
  8692. *!
  8693. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8694. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8695. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8696. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8697. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8698. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8699. *!
  8700. *!*****************************************************************************
  8701. FUNCTION tock
  8702. *)
  8703. *) INITTICK, TICK, and TOCK - Profiling functions
  8704. *)
  8705. PARAMETER m.bucket
  8706. ticktock[bucket] = ticktock[bucket] + SECONDS()
  8707. RETURN 
  8708.  
  8709. *!*****************************************************************************
  8710. *!
  8711. *!      Procedure: PUTMSG
  8712. *!
  8713. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8714. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8715. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8716. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8717. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8718. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8719. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8720. *!
  8721. *!*****************************************************************************
  8722. PROCEDURE putmsg
  8723. *)
  8724. *) Display a status message on the status bar at the bottom of the screen
  8725. *)
  8726. PARAMETER m.msg
  8727. IF m.g_graphic
  8728.    SET MESSAGE TO msg
  8729. ENDIF
  8730.  
  8731. *!*****************************************************************************
  8732. *!
  8733. *!       Function: VERSIONCAP
  8734. *!
  8735. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8736. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8737. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8738. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8739. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8740. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  8741. *!
  8742. *!*****************************************************************************
  8743. FUNCTION versioncap
  8744. *)
  8745. *) VERSIONCAP - Return platform name suitable for display
  8746. *)
  8747. PARAMETER m.strg, m.dual
  8748. DO CASE
  8749. CASE m.strg = "DOS"
  8750.    m.retstrg = "MS-DOS"
  8751.     IF m.dual
  8752.        m.retstrg = m.retstrg + " and UNIX"
  8753.     ENDIF
  8754. CASE m.strg = "WINDOWS"
  8755.    m.retstrg = "Windows"
  8756.     IF m.dual
  8757.        m.retstrg = m.retstrg + " and Macintosh"
  8758.     ENDIF
  8759. CASE m.strg = "MAC"
  8760.    m.retstrg = "Macintosh"
  8761.     IF m.dual
  8762.        m.retstrg = m.retstrg + " and Windows"
  8763.     ENDIF
  8764. CASE m.strg = "UNIX"
  8765.    m.retstrg = "UNIX"
  8766.     IF m.dual
  8767.        m.retstrg = m.retstrg + " and MS-DOS"
  8768.     ENDIF
  8769. OTHERWISE
  8770.    m.retstrg = m.strg
  8771. ENDCASE
  8772. RETURN m.retstrg
  8773.  
  8774. *!*****************************************************************************
  8775. *!
  8776. *!       Function: MULTIPLAT
  8777. *!
  8778. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8779. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8780. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8781. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8782. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8783. *!
  8784. *!*****************************************************************************
  8785. FUNCTION multiplat
  8786. *)
  8787. *) MULTIPLAT - Returns TRUE if we are generating for multiple platforms
  8788. *)
  8789. RETURN IIF(m.g_allplatforms AND m.g_numplatforms > 1, .T. , .F.)
  8790.  
  8791. *!*****************************************************************************
  8792. *!
  8793. *!      Procedure: SEEKHEADER
  8794. *!
  8795. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8796. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8797. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8798. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8799. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  8800. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8801. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  8802. *!
  8803. *!*****************************************************************************
  8804. PROCEDURE seekheader
  8805. *)
  8806. *) SEEKHEADER - Find the header for this screen/platform
  8807. *)
  8808. PARAMETER m.i
  8809. IF g_screens[m.i,6]
  8810.    GO TOP
  8811. ELSE
  8812.    LOCATE FOR platform = g_screens[m.i,7] AND objtype = c_otscreen
  8813. ENDIF
  8814. RETURN 
  8815.  
  8816. *!*****************************************************************************
  8817. *!
  8818. *!       Function: GETPLATNAME
  8819. *!
  8820. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8821. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8822. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8823. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8824. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  8825. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  8826. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  8827. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  8828. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  8829. *!
  8830. *!*****************************************************************************
  8831. FUNCTION getplatname
  8832. *)
  8833. *) GETPLATNAME - Return the platform for a screen
  8834. *)
  8835. PARAMETER m.plnum
  8836. IF g_screens[m.plnum,6]
  8837.    RETURN "DOS"
  8838. ELSE
  8839.    RETURN platform
  8840. ENDIF
  8841. RETURN 
  8842.  
  8843.  
  8844. *!*****************************************************************************
  8845. *!
  8846. *!      Procedure: INSERTFILE
  8847. *!
  8848. *!      Called by: GENINSERTCODE      (procedure in GENSCRN.PRG)
  8849. *!
  8850. *!          Calls: WRITECODE          (procedure in GENSCRN.PRG)
  8851. *!
  8852. *!*****************************************************************************
  8853. PROCEDURE insertfile
  8854. PARAMETER m.incfn, m.scrnno, m.insetup, m.platname
  8855. PRIVATE m.oldals, m.insdbfname, m.oldmline, m.fptname
  8856.  
  8857. * Search for the file in the current directory, along the FoxPro path, and along
  8858. * the DOS path.
  8859. IF !FILE(m.incfn)
  8860.    DO CASE
  8861.    CASE FILE(FULLPATH(m.incfn))
  8862.       m.incfn = FULLPATH(m.incfn)
  8863.    CASE FILE(FULLPATH(m.incfn,1))
  8864.       m.incfn = FULLPATH(m.incfn,1)
  8865.    ENDCASE
  8866. ENDIF
  8867.  
  8868. IF FILE((m.incfn))
  8869.    m.oldals = ALIAS()
  8870.    m.insdbfname = SYS(3)+".DBF"
  8871.    m.oldmline = _MLINE
  8872.  
  8873.    * The following lines create a temporary file with a single memo field
  8874.    * and appends the inserted file into the memo field. Effectively creating
  8875.    * a code snippet. This allows the standard procedure for generating code
  8876.    * snippets to be call to process the inserted file. This in turn allows
  8877.    * the include file to contain generator directives.
  8878.    CREATE TABLE (m.insdbfname) (inscode m)
  8879.    APPEND BLANK
  8880.    APPEND MEMO inscode FROM (m.incfn)
  8881.  
  8882.    \** Start of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,32)+"start">>
  8883.  
  8884.    * Make a recursive call to the standard snippet generation procedure
  8885.    DO writecode WITH inscode, m.platname, 1, 0, m.scrnno, m.insetup
  8886.  
  8887.    \** End of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,36)+"end">>
  8888.    \
  8889.  
  8890.    USE
  8891.    DELETE FILE (m.insdbfname)
  8892.    m.fptname = forceext(m.insdbfname,"FPT")
  8893.    IF FILE(m.fptname)
  8894.       DELETE FILE (m.fptname)
  8895.    ENDIF
  8896.    
  8897.    SELECT (m.oldals)
  8898.    _MLINE=oldmline
  8899. ELSE
  8900.    \*
  8901.    \* Inserted file <<m.incfn>> not found!
  8902.    \*
  8903. ENDIF
  8904. RETURN
  8905.  
  8906. *!*****************************************************************************
  8907. *!
  8908. *!      Function: VERSNUM
  8909. *!
  8910. *!*****************************************************************************
  8911. FUNCTION versnum
  8912. * Return string corresponding to FoxPro version number
  8913. RETURN wordnum(vers(),2)
  8914.  
  8915.  
  8916. *!*****************************************************************************
  8917. *!
  8918. *!      Function: SHOWSTAT
  8919. *!
  8920. *!*****************************************************************************
  8921. PROCEDURE showstat
  8922. PARAMETER m.strg
  8923. WAIT WINDOW m.strg NOWAIT
  8924. RETURN 
  8925.  
  8926. *!*****************************************************************************
  8927. *!
  8928. *!      Function: KILLCR
  8929. *!
  8930. *!*****************************************************************************
  8931. PROCEDURE killcr
  8932. PARAMETER m.strg
  8933. IF _MAC
  8934.    m.strg = CHRTRAN(m.strg,CHR(13)+CHR(10),"")
  8935. ENDIF
  8936. RETURN 
  8937.  
  8938. *!*****************************************************************************
  8939. *!
  8940. *!      Function: ASSERT
  8941. *!
  8942. *!*****************************************************************************
  8943. FUNCTION assert
  8944. PARAMETER m.bool, m.strg
  8945. IF !m.bool
  8946.    WAIT WINDOW m.strg
  8947. ENDIF
  8948.  
  8949. *!*****************************************************************************
  8950. *!
  8951. *!      Function: BITMAPSTR
  8952. *!
  8953. *!*****************************************************************************
  8954. FUNCTION bitmapstr
  8955. * Return a string of bitmap file extensions, suitable for LOCFILE, etc.
  8956. PARAMETER whichone
  8957. DO CASE
  8958. CASE whichone = c_all AND _MAC
  8959.    RETURN '"'+m.g_picext+"|"+m.g_bmpext+"|"+m.g_icnext+"|"+m.g_icoext+'"'
  8960. CASE whichone = c_all AND !_MAC
  8961.    RETURN '"'+m.g_bmpext+"|"+m.g_icoext+"|"+m.g_picext+"|"+m.g_icnext+'"'
  8962. OTHERWISE
  8963.    RETURN '"'+IIF(_MAC,m.g_picext,m.g_bmpext)+'"'
  8964. ENDCASE
  8965.  
  8966. *!*****************************************************************************
  8967. *!
  8968. *!      Function: ICONSTR
  8969. *!
  8970. *!*****************************************************************************
  8971. FUNCTION iconstr
  8972. DO CASE
  8973. CASE _MAC
  8974.     RETURN m.g_icnext
  8975. OTHERWISE
  8976.     RETURN m.g_icoext
  8977. ENDCASE
  8978.  
  8979. *!*****************************************************************************
  8980. *!
  8981. *!      Function: STYLE2NUM
  8982. *!
  8983. *!*****************************************************************************
  8984. FUNCTION style2num
  8985. * Translate a font style string to its equivalent numerical representation
  8986. PARAMETER m.strg
  8987. PRIVATE m.i, m.num
  8988. m.num = 0
  8989. m.strg= UPPER(ALLTRIM(m.strg))
  8990. FOR m.i = 1 TO LEN(m.strg)
  8991.    DO CASE
  8992.    CASE SUBSTR(m.strg,i,1) = "B"      && bold
  8993.       m.num = m.num + 1
  8994.    CASE SUBSTR(m.strg,i,1) = "I"         && italic
  8995.       m.num = m.num + 2
  8996.    CASE SUBSTR(m.strg,i,1) = "U"      && underlined
  8997.       m.num = m.num + 4
  8998.    CASE SUBSTR(m.strg,i,1) = "O"      && outline
  8999.       m.num = m.num + 8
  9000.    CASE SUBSTR(m.strg,i,1) = "S"      && shadow
  9001.       m.num = m.num + 16
  9002.    CASE SUBSTR(m.strg,i,1) = "C"         && condensed
  9003.       m.num = m.num + 32
  9004.    CASE SUBSTR(m.strg,i,1) = "E"      && extended
  9005.       m.num = m.num + 64
  9006.    CASE SUBSTR(m.strg,i,1) = "-"      && strikeout
  9007.       m.num = m.num + 128
  9008.    ENDCASE
  9009. ENDFOR
  9010. RETURN m.num
  9011.  
  9012. *!*****************************************************************************
  9013. *!
  9014. *!      Function: NUM2STYLE
  9015. *!
  9016. *!*****************************************************************************
  9017. FUNCTION num2style
  9018. * Translate a font style number to its equivalent string representation
  9019. PARAMETER m.num
  9020. PRIVATE m.i, m.strg, m.pow, m.stylechars, m.outstrg
  9021. m.strg = ""
  9022. * These are the style characters.  Their position in the string matches the bit 
  9023. * position in the num byte.
  9024. m.stylechars = "BIUOSCE-"
  9025.  
  9026. * Look at each of the bits in the num byte
  9027. FOR m.i = 8 TO 1 STEP -1
  9028.    m.pow = ROUND(2^(i-1),0)  
  9029.     IF m.num >= m.pow
  9030.        m.strg = m.strg + SUBSTR(stylechars,m.i,1)
  9031.     ENDIF
  9032.     m.num = m.num % m.pow
  9033. ENDFOR
  9034.  
  9035. * Now reverse the string so that style codes appear in the traditional order
  9036. m.outstrg = ""
  9037. FOR m.i = 1 TO LEN(m.strg)
  9038.    m.outstrg = m.outstrg + SUBSTR(m.strg,LEN(m.strg)+1-m.i,1)
  9039. ENDFOR
  9040. RETURN m.outstrg
  9041.  
  9042.  
  9043. FUNCTION ctrlclause
  9044. PARAMETER m.pictstrg
  9045. * Return the control portion of a picture string
  9046. m.pictstrg = LTRIM(m.pictstrg)
  9047. m.spos = AT(' ',m.pictstrg)
  9048. IF m.spos > 1
  9049.     IF INLIST(LEFT(m.pictstrg,1),'"',"'")
  9050.        m.pictstrg = STRTRAN(m.pictstrg,LEFT(m.pictstrg,1),"")
  9051.     ENDIF
  9052.    RETURN ALLTRIM(LEFT(m.pictstrg,m.spos - 1))
  9053. ELSE
  9054.    RETURN m.pictstrg
  9055. ENDIF
  9056.  
  9057.  
  9058. *: EOF: GENSCRN.PRG
  9059.